【Android】四大組件歸納總結
- 2020 年 3 月 15 日
- 筆記
隨著學習持續更新
四大組件均可使用android:process="name"在Manifest中聲明成獨立進程
Activity
生命周期

4種啟動模式
Android使用回退棧來管理Activity實例。當前顯示的Activity在棧頂,當點擊後退或返回時,棧頂的Activity出棧。
可以指定Activity的啟動模式來避免重複創建同一Activity
在AndroidManifest.xml中聲明Activity的啟動模式
<activity android:name=".MyActivity" android:lauchMode="singleTask"></activity> standard
默認的啟動模式,允許Activity被多次實例化,一個任務棧中會有多個Activity實例
singleTop
處於棧頂的Activity會被重用,若不在棧頂則會被重新創建。重用時會調用原來實例的
onNewIntent()函數singleTask(常用)
一個任務棧只允許存在一個Activity實例,當
startActivity()時,若該Activity在棧內,則會將該Activity上的所有Activity銷毀,使該Activity處於棧頂,並調用onNewIntent()方法singleInstance
一個Activity在獨立的任務中開啟,保證在系統中只有一個實例,所有的
startActivity()都會重用該實例,並回調onNewIntent()方法
兩個Activity互相切換時的生命周期
A:onCreate->onStart->onResume
這是在A中啟動B活動,生命周期如下:
A: onPause
B: onCreate->onStart->onResume
A: onStop
從B中返回A活動時
B: onPause
A: onRestart->onStart->onResume
B: onStop->onDestroy
Service
當程式進入後台運行時,所需要做的操作可以通過Service實現。
在任何位置調用startService()啟動服務。
每個服務只存在一個實例,每次調用startService()時會回調onStartCommand();只需要調用一次stopService()或stopSelf()函數,服務會被停止。
普通Service運行在UI執行緒,若需要執行耗時操作需要新開執行緒。
生命周期
onCreate()onStartCommand(intent, flags, startId)有三種返回值
- START_STICKY:當服務因記憶體不足被kill掉後,記憶體空閑時會嘗試重建服務,重建成功則回調
onStartCommand(),這是傳入的intent為null - START_NOT_STICKY:當Service因記憶體不足而被系統kill後,即使系統記憶體再次空閑時,系統也不會嘗試重新創建此Service
- START_REDELIVER_INTENT:當Service因記憶體不足而被系統kill後,則會重建服務,並通過傳遞給服務的最後一個 Intent 調用
onStartCommand(),這個值適用於主動執行應該立即恢復的作業(例如下載文件)的服務
- START_STICKY:當服務因記憶體不足被kill掉後,記憶體空閑時會嘗試重建服務,重建成功則回調
onDestroy()調用
stopService()或stopSelf()
IntentService
重寫onHandleIntent()函數,在函數中完成耗時操作。IntentService會自動將操作執行在子執行緒中,並在完成時調用stopSelf()自我銷毀
public class MyIntentService extends IntentService { @Override protected void onHandleIntent(Intent intent) { ... } } Binder(與服務連接)
當服務僅限本地應用使用,不需要跨進程工作,則可以實現自有的Binder類,讓客戶端通過該類直接訪問服務中的公共方法。
首先需要創建ServiceConnection對象,代表與服務的連接,有兩個方法
onServiceConnected(name, serivce)系統會調用該方法傳遞服務的
onBind()方法返回的IBinder, 通過該對象可以調用獲取到Service的實例對象,進而調用服務端的公共方法。onServiceDisconnected(name)系統與服務意外中斷時調用,unBind不會調用該方法
調用bindService(intent, ServiceConnection, flag)綁定相關服務,flag指綁定時是否自動創建Service,0表示不創建;BIND_AUTO_CREATE表示自動創建。
調用unbindService(ServiceConnection)
當最後一個客戶端與服務取消綁定時,系統會將服務銷毀
前台服務
startForeground(int id, Notification notification)將當前服務設成前台服務,id參數為唯一標識通知的整型數,不得為0
stopForeground(boolean removeNotification)
Android8.0後需要開啟前台服務要在Activity中startForegroundService(i),且之後Service要在5s內調用startForeground()才能成功創建前台服務
如何保證Service不被殺死
記憶體資源不足
- 將
onStartCommand()返回值設成START_STICKY或START_REDELIVER_INTENT,這樣記憶體組後也會恢復服務 - 將服務設成前台服務,具備較高優先順序
- 將
用戶手動干預
如果不是force stop則會調用生命周期中的
onDestroy()方法,可以在方法中發送廣播重啟服務。完備一些的話就啟動兩個服務,相互監聽,相互重啟。
Broadcast
組成:發送廣播的Broadcast,接受廣播的BroadcastReceiver和傳遞消息的Intent。
類型:普通廣播、有序廣播、本地廣播(LocalBroadcast)、Sticky廣播
靜態廣播與動態廣播
廣播可分為靜態註冊和動態註冊兩種形式
靜態註冊
在Manifest.xml中聲明靜態廣播
<receiver android:name=".MyReceiver"> <intent-filter android:priority=1000> <action android:name="com.broadcast" </intent-filter> </receiver>動態註冊
可以在
onCreate的時候註冊MyBroadcastReceiver receiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter("my.action"); context.registerReceiver(receiver, filter);在
onDestroy的時候註銷unregisterReceiver(receiver);靜態廣播與動態廣播的區別
- 靜態廣播在activity註銷的時候也能夠繼續接收;動態廣播在APP退出後就無法接收了
- 動態廣播在相同Priority下優先順序比靜態廣播高
普通廣播
非同步廣播,調用sendBroadcast(new Intent(ACTION))來發出廣播
定義廣播接收器
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ... } } 在AndroidManifest.xml中註冊:
<receiver android:name=".broadcast.MyBroadcastReceiver"> <intent-filter> <action android:name=".."/> </intent-filter> </receiver> 動態註冊接收器:
registerReceiver(new MyBroadcastReceiver(), new IntentFilter(MY_ACTION)); 有序廣播
發送出去的廣播被廣播的接收者按照先後順序接收
接收的順序排序
- 按照Priority屬性值從大到小
- Priority相同則動態註冊廣播優先
本地廣播
只限於應用的廣播
使用LocalBroadcastManager.getInstance(context)來使用關於廣播的操作函數:
registerReceiver(receiver, intentFilter)unregisterReceiver(receiver)sendBroadcast(new Intent(INTENT_NAME))sendBroadcastSync(new Intent())
註冊本地廣播
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); mReceiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_MY_TYPE); mLocalBroadcastManager.registerReceiver(mReceiver,filter); 需要在onDestory()的中進行註銷:
mLocalBroadcastManager.unregisterReceiver(mReceiver) ContentProvider
ContentProvider可以將應用中的數據共享給其他應用訪問,其他應用可以通過ContentProvider對應用中的數據進行增刪改查。
也可以進行進程間數據的交互和共享,跨進程通訊。

