【Android】四大組件歸納總結

  • 2020 年 3 月 15 日
  • 筆記

隨著學習持續更新

四大組件均可使用android:process="name"在Manifest中聲明成獨立進程

Activity

生命周期

image-20200122100121384

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

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()自我銷毀

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

組成:發送廣播的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);
  • 靜態廣播與動態廣播的區別

    1. 靜態廣播在activity註銷的時候也能夠繼續接收;動態廣播在APP退出後就無法接收了
    2. 動態廣播在相同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對應用中的數據進行增刪改查。

也可以進行進程間數據的交互和共享,跨進程通訊。

Tags: