2019-06-04

Activity的生命周期

正常的流程:

onCreate():被創(chuàng)建的時候被回調(diào),

onStart():Activity正在啟動狀態(tài),處于可見但無法交互,但處在后臺

onResume():已經(jīng)在前臺可見,可以和用戶交互,Activity已經(jīng)在運行

onPause():Activity正在停止,和onResume()成對出現(xiàn)

onStop():即將停止,或被新的Activity覆蓋,Activity不可見,在后臺運行

onDestory():Activity正在被銷毀,回收和資源的釋放,和onCreate()成對

onRestart():Activity正在重新啟動不會執(zhí)行此方法

異常的流程(1、系統(tǒng)發(fā)生改變 2、內(nèi)存不足造成的改變):

只有在Activity異常的情況下才會調(diào)用

onSaveInstanceState()是出現(xiàn)異常情況下,會自動調(diào)用,來保存當前Activity的信息,(當異常啟動的時候,這個方法中的bunlder可能為空,所以要進行非空判斷)

onRestoreInstanceState()當Activity重新創(chuàng)建后,自動調(diào)用,會通過onSaveInstanceState()的Bundle來保存狀態(tài)

一旦被異常啟動,Bundle()方法不會為空

總結(jié): 1、Activity正常啟動:onCreate--onStart--onResume

2、點擊Back回退:onPause--onStop--onDestroy

3、打開新的Activity:onPause--onStop

4、Activity異常:onSaveInstanceState來保存數(shù)據(jù)

5、Activity重新創(chuàng)建:調(diào)用onRestoreInstanceState


1.任務棧????

四種形態(tài):

Active:Activity處于棧頂

Paused:可見但不可交互? 只是失去了和用戶的交互,只有在系統(tǒng)內(nèi)存不足時才會被回收

Stopped:不可見? 被完全覆蓋時,只有在系統(tǒng)內(nèi)存不足時才會被回收

Killed:系統(tǒng)回收掉

(在內(nèi)存不足的時候,會回收棧底部的Activity)

總結(jié):1、Activity是與用戶交互的接口 2、Android系統(tǒng)是通過Activity棧的形式來管理Activity 3、四種形態(tài):Active/Paused/Stopped/Killed

2.四種啟動模式

Activity啟動模式(當多次啟動Activity的時候,系統(tǒng)會創(chuàng)建多個實例,按照先后進出的順序放入任務棧中,當按下Back鍵的時候,整個任務棧就會為空,系統(tǒng)就會回收)

1、standard(標準模式)(默認啟動模式)

一、在不指定啟動模式的前提下,系統(tǒng)默認使用該模式啟動每個Activity

二、每次啟動一個Activity都會重寫創(chuàng)建一個新的實例(消耗資源)

三、Activity在啟動的時候,onCreate(),onStart(),onResume()都會依次調(diào)用

2、singleTop(棧頂復用) ps:只有在棧頂才可以

一、當前棧中已有該Activity實例并且該實例位于棧頂時

二、當前棧中已有該Activity實例單實該實例不再棧頂時

三、當前棧中不存在該Activity的實例

SingleTop應用場景:

IM對話框

新聞客戶端推送

3、singleTask(棧內(nèi)復用模式),檢測的是整個棧中是否存在要啟動的Activity

(適合于應用中主界面模式)

一、首先根據(jù)taskAffinity去尋找當前是否存在一個對應名字(就是包名)的任務棧

(任務相關(guān)性)

二、如果不存在,就重新創(chuàng)建一個Task任務棧

然后創(chuàng)建新的Activity的實例假如棧中

三、如果存在,先得到該任務棧,查找該任務棧中是否存在該Activity實例

存在的話,就會將所有這個實例的Activity都出棧

SingleTask應用場景

應用的主界面

4、singleInstance(單一實例模式)

singleInstance模式下,所有的Activity中只有一個實例,所有Activity會獨享一個任務棧

如果有別的Activity使用的話,這兩個Activity會使用一個任務棧

應用場景:呼叫來電、

特性:

1、以SingleInstance模式啟動的Activity具有全局唯一性

2、如果在啟動這樣的Activity時,已經(jīng)存在了一個實例

3、以SingleInstance模式啟動的Activity具有獨占性



Activity和Activity之間的通信

1、Intent/Bundle

Intent:首先創(chuàng)建Bundle對象,通過Key,Value傳遞數(shù)據(jù)

例:

第一個Activity發(fā)送

Bundle bundle = new Bundle();

bundle.putString("Key","value");

bundle.putInt("Key2",1);

Intent intent = new Intent(GoActivity.this,ToActivity.class);

intent.putExtras(bundle);

startActivity(intent);

將Bundle對象和Intent建立聯(lián)系

第二個Activity接收

Intent intent = getIntent();

String key = intent.getStringExtra("Key");

int value = intent.getIntExtra("Key2",1);

第二個Activity中獲取第一個Activity傳過來的值

2、類靜態(tài)變量

3、全局變量

Activity和Service之間的通信

1、綁定服務,利用ServiceConnection類

在Activity中實現(xiàn)接口(ServiceConnection)

重寫onServiceConnected(綁定成功執(zhí)行) onServiceDisconnected(進程崩潰執(zhí)行)這兩個方法,這兩個方法是在綁定成功和進程崩潰的時候調(diào)用

首先在onServiceConnected()中創(chuàng)建Binder對象,利用binder的setData()方法,向Service中傳遞數(shù)據(jù)

2、簡單通信,利用Intent進行傳值

用Intent進行傳值,從Activity中傳值(putExtras.("key","value"))

在Service中直接用(getIntent)獲取

3、定義一個CallBack接口來監(jiān)聽服務中的進程的變化

在Service中定義一個接口

在Activity中,在onServiceConnected()方法中,用binder對象來實現(xiàn)Callback中重寫的方法

如果是在子線程中,需要通過Handler來發(fā)送到主線程中,

Activity和Fragment之間的通信

Activity將數(shù)據(jù)傳遞給Fragment

Bundle:

當用Bundle來傳遞數(shù)據(jù)時,用fragment.setArguments(bundle對象名);

在Fragment的時候,用(isAdded()方法)判斷是否已經(jīng)依附在Activity上。

直接在Activity中定義方法:

在第一個Activity中定義構(gòu)造方法

然后在需要接收數(shù)據(jù)的Fragment中用onAttach()方法中強轉(zhuǎn)為Activity的類型

Fragment將數(shù)據(jù)傳遞給Activity

1、接口回調(diào):

一、在fragment中定義一個內(nèi)部回調(diào)接口//Acticity實現(xiàn)這個接口就行

二、fragment的方法onAttch()//檢查fragment中是否實現(xiàn)了內(nèi)部接口

三、調(diào)用onDetach方法,銷毀,把Activity傳過來的資源釋放


Fragment與Service數(shù)據(jù)通信

Activity調(diào)用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service對象的一個引用,這樣Activity可以直接調(diào)用到Service中的方法,如果要主動通知Activity,我們可以利用回調(diào)方法

?Service向Activity發(fā)送消息,可以使用廣播,當然Activity要注冊相應的接收器。比如Service要向多個Activity發(fā)送同樣的消息的話,用這種方法就更好


Fragment復用

?為什么要復用Fragment?

Activity 在重建的時候會恢復其包含的 FragmentManager ,F(xiàn)ragmentManager 又會恢復其管理的 Fragment ,同理 Fragment 也會恢復其包含的 FragmentManager,層層遞進,直到全部恢復

復用的好處:

避免顯示錯亂

避免重復添加

避免多余的內(nèi)存占用

優(yōu)化界面啟動速度


兩種適配器的區(qū)別?

(1).FragmentPagerAdapter

適合于?Fragment數(shù)量不多的情況。當某個頁面不可見時,該頁面對應的View可能會被銷毀,

但是所有的Fragment都會一直存在于內(nèi)存中。

如果Fragment需要保存的狀態(tài)較多時,會導致占用內(nèi)存較大,

(2).FragmentStatePagerAdapter

適合于Fragment數(shù)量較多的情況。當頁面不可見時,?對應的Fragment實例可能會被銷毀,

但是Fragment的狀態(tài)會被保存。

因此每個Fragment占用的內(nèi)存會更少,但是頁面切換會引起較大開銷。

1、service和線程(Thread)的區(qū)別和場景

Thread:程序執(zhí)行的最小單元,它是分配CPU的基本單位

Thread:生命周期

1.新建new

2.就緒runnable

3.運行running

4.死亡death

5.阻塞block

缺點:無法控制,當Activity被關(guān)閉之后,無法控制線程

場景:Thread需要連續(xù)不斷地每隔一段時間就要連接服務器一次做某種操作

2、如何管理service生命周期

不管如何啟動service,oncreate()和ondestory()都會運行

Service運行在后臺

Service時Android的一種機制,服務是運行在主線程上的

Service生命周期:

onCreate()通過onCreate開始

onStart()

onDestroy()到onDestory結(jié)束

onBind()

onUnbind()

四種情況:

1:StartService:

2:stopService:

3:bindService:

4:unBindService:

3、Service和IntentService的區(qū)別

Service:不建議在service中執(zhí)行耗時操作,否則會報ANR

IntentService:內(nèi)部有一個工作線程HandlerThread來處理耗時操作


工作機制:繼承與Service,

和Service不同點:在onCreate()方法中會創(chuàng)建并啟動HandlerThread,還創(chuàng)建了ServiceHandler異步處理類,執(zhí)行異步任務

當持有IntentService會實現(xiàn)onHandlerIntent方法,

如果后臺只有一個任務,執(zhí)行完onHandlerIntent會進行銷毀

如果后臺有很多任務,onHandlerIntent會依次執(zhí)行,直到執(zhí)行完畢之后,才會銷毀(調(diào)用StopSelf()結(jié)束操作)

總結(jié):

1、IntentService是繼承并處理異步請求的一個類

2、內(nèi)有一個工作線程(也就是HandlerThread)來處理耗時操作

3、IntentService內(nèi)部則是通過消息的方式發(fā)送給HandlerThread的,然后由Handler中的Looper來處理消息

4、啟動服務和綁定服務先后次序問題

Android中只會又一個服務

啟動服務:service會無限期的運行

先綁定service后啟動

綁定服務會轉(zhuǎn)為啟動服務狀態(tài),不會影響服務運行,之到onStop為止

先啟動service后綁定

不會轉(zhuǎn)為綁定的狀態(tài),當Activity解除綁定服務的時候,還會按照啟動的生命周期在后臺運行,之到onStop為止

總結(jié): 1、啟動服務的優(yōu)先級比綁定服務高

2、服務在其托管進程的主線程中執(zhí)行,主線程

ALDL:

AIDL:是一種android內(nèi)部進程通信接口描述語言,用過它我們可以定義進程間的通信接口但是記住僅僅只是 android ,換個平臺就不是AIDL 了。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AIDL進程間通訊的原理:

? 1.通過編寫aidl文件夾來定義進程間通信接口

? 2.編譯后會自動生成相應的java文件? 在各未見中我們可以看到是繼承啦一個Binder對象,實現(xiàn)剛剛定義的接口

? 3.服務器我們通過一個服務實現(xiàn)里面的Binder方法,將接口的具體實現(xiàn)寫在stub中,用ibinder對象傳遞給客戶端

? 4.客戶端bindservice的時候,服務是實現(xiàn)serviceConnection重寫里面的方法,用asinterface的形式將ibinder還原成接口,在調(diào)用其接口中的方法來實現(xiàn)通信


Binder機制:

???????? Android使用Linux內(nèi)核擁有這非常多的跨進程通信機制,比如Socket,管道。為什么還要binder呢?

性能:Binder相比較于傳統(tǒng)的socket/管道通信而言,更加高效,它在IPC時,只需要數(shù)據(jù)拷貝1次,而傳統(tǒng)的socket之類的需要2次;

出于安全上的考慮:傳統(tǒng)的進程間通信對于通信雙方的身份沒有進行嚴格的驗證,只有上層協(xié)議才會進行架構(gòu),比如說,socket通信時,IP地址是手動填寫的,可以進行人為的偽造,而Binder支持通信雙方進行身份校驗,極大的保障了安全性;

Binder的通信模型:

我們其實可以進程通信的雙方一方稱為服務端進程,另一方稱為客戶端進程,我們知道,由于進程隔離的存在,在不進行進程間通信的方式的情況下,客戶端進程是無法訪問服務端進程的;

對于A和B相當于兩個進程,他們要打電話就相當于要進行通信,其中電話基站就想到與Binder驅(qū)動,而通信錄則相當于其中的一個ServerManager

ServerManager其實就是一個進程,它里面維護了一張表,表里面存儲的是向他注冊過的進程信息,在通信之初,首先需要有一個進程向驅(qū)動申請成為ServerManager,當內(nèi)核驅(qū)動同意之后,這個成為ServerManager的進程就負責管理所有需要通信的進程信息,當客戶端進程要訪問服務端進程時,服務端進程首先會向ServerManager注冊,讓ServerManager保存自己的有關(guān)信息,當ServerManger保存完畢后,客戶端進程就會通過Binder驅(qū)動向ServerManger查詢服務端進程的信息,ServerManage就會將服務端進程的信息返回給客戶端進程,客戶端與服務端進程之間就可以通過這些信息,利用Binder驅(qū)動來進行通信了;

總結(jié)來說,Binder通信機制分三步:

第一步:ServerManager在其內(nèi)部維護一張表;

第二步:服務端進程向ServerManager注冊信息;

第三步:客戶端進程向ServerManager取得信息,通過Binder驅(qū)動與服務端進程通信;

手寫網(wǎng)絡框架:理解http網(wǎng)絡請求的過程,會存在的問題記錄下來,對比okhttp, 為啥要手寫?

問題?

擴展性:不能只處理Json/Xml,image,file,video

易用性:解決問題只需要調(diào)用一兩個API

穩(wěn)定性,封裝性,模塊化

和其他框架能不能集成(數(shù)據(jù)庫,網(wǎng)絡,MVC,MVVM,資源加載)

對比?

okhttp:

1.占用儲存空間

okhttp占用內(nèi)存空間過大。

2.功能介紹

Square 公司開源的 OkHttp 是一個專注于連接效率的 HTTP 客戶端。OkHttp 提供了對 HTTP/2 和 SPDY 的支持,并提供了連接池,GZIP 壓縮和 HTTP 響應緩存功能。

3.優(yōu)點

支持http請求,https請求。

支持文件下載。

使用的是HttpURLConnection,不要擔心android版本的變換。(至少目前是都支持的)。

支持get,post請求。

基于Http的文件上傳。

加載圖片。

4.缺點

比如callback回來是在線程里面, 不能刷新UI,需要我們手動處理。

封裝比較麻煩。

Volley

1.占用儲存空間

占用內(nèi)存空間小。

2.功能介紹

Volley是Goole在2013年Google I/O大會上推出了一個新的網(wǎng)絡通信框架,它是開源的。

Volley 的特點:特別適合數(shù)據(jù)量小,通信頻繁的網(wǎng)絡操作。

3.優(yōu)點

非常適合進行數(shù)據(jù)量不大,但通信頻繁的網(wǎng)絡操作。

內(nèi)部分裝了異步線程。

支持get,post網(wǎng)絡請求。

圖片下載。

可直接在主線程調(diào)用服務端并處理返回結(jié)果。

可以取消請求,容易擴展,面向接口編程。

4.缺點

對大文件下載 Volley的表現(xiàn)非常糟糕。

只支持http請求。

為啥手寫?

因為在項目中,可以使代碼簡介明了,做到代碼職責劃分明顯,實現(xiàn)某一塊功能不會有多余的代碼,而使用別人的開源框架會使我們的代碼混亂,代碼過多,不簡潔,從而導致App的內(nèi)存占用太大,而且某些開源框架,不能滿足我們功能上的需求,而且自己寫的更方便自己理解和修改。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容