1. 程式人生 > >【Android】四大元件歸納總結

【Android】四大元件歸納總結

> 隨著學習持續更新 四大元件均可使用`android:process="name"`在Manifest中宣告成獨立程序 ## Activity #### 生命週期 ![image-20200122100121384](https://developer.android.google.cn/guide/components/images/activity_lifecycle.png?hl=zh-cn) #### 4種啟動模式 Android使用回退棧來管理Activity例項。當前顯示的Activity在棧頂,當點選後退或返回時,棧頂的Activity出棧。 可以指定Activity的啟動模式來避免重複建立同一Activity 在AndroidManifest.xml中宣告Activity的啟動模式 ```xml ``` - 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 > [https://blog.csdn.net/javazejian/article/details/52709857](https://blog.csdn.net/javazejian/article/details/52709857) 當程式進入後臺執行時,所需要做的操作可以通過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()`,這個值適用於主動執行應該立即恢復的作業(例如下載檔案)的服務 - `onDestroy()` 呼叫`stopService()`或`stopSelf()` #### IntentService 重寫`onHandleIntent()`函式,在函式中完成耗時操作。IntentService會自動將操作執行在子執行緒中,並在完成時呼叫`stopSelf()`自我銷燬 ```java 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 > [https://www.jianshu.com/p/ca3d87a4cdf3](https://www.jianshu.com/p/ca3d87a4cdf3) 組成:傳送廣播的Broadcast,接受廣播的BroadcastReceiver和傳遞訊息的Intent。 型別:普通廣播、有序廣播、本地廣播(LocalBroadcast)、Sticky廣播 #### 靜態廣播與動態廣播 廣播可分為靜態註冊和動態註冊兩種形式 - 靜態註冊 在Manifest.xml中宣告靜態廣播 ```xml
``` - 動態註冊 可以在`onCreate`的時候註冊 ```java MyBroadcastReceiver receiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter("my.action"); context.registerReceiver(receiver, filter); ``` 在`onDestroy`的時候登出 ```java unregisterReceiver(receiver); ``` - 靜態廣播與動態廣播的區別 1. 靜態廣播在activity登出的時候也能夠繼續接收;動態廣播在APP退出後就無法接收了 2. 動態廣播在相同Priority下優先順序比靜態廣播高 #### 普通廣播 非同步廣播,呼叫`sendBroadcast(new Intent(ACTION))`來發出廣播 定義廣播接收器 ```java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ... } } ``` 在AndroidManifest.xml中註冊: ```xml
``` 動態註冊接收器: ```java 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())` 註冊本地廣播 ```java mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); mReceiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_MY_TYPE); mLocalBroadcastManager.registerReceiver(mReceiver,filter); ``` 需要在`onDestory()`的中進行登出: ```java mLocalBroadcastManager.unregisterReceiver(mReceiver) ``` ## ContentProvider ContentProvider可以將應用中的資料共享給其他應用訪問,其他應用可以通過ContentProvider對應用中的資料進行增刪改查。 也可以進行程序間資料的互動和共享,跨程序