你不知道Android四大組件祕密

Android四大組件用了很多遍了,但還是有很多細節容易忘記,所以就寫下來吧!

Activity

Activity的生命週期

 

在這裏插入圖片描述

Activity的簡單生命週期流程爲onCreate();→onStart();【注:此時Activity處於不可見狀態】→onResume();【注:此時Activity處於運行狀態】→onPause();【注:此時Activity處於暫停狀態】→onStop();【注:此時Activity處於停滯狀態】→onDestroy();【注:調用了此方法後Activity生命週期結束】
其中當Activity正在重新啓動的時候,從不可見變爲可見的時候,會調用到onRestart();也就是說一個Activity包含七個生命週期流程

  • Activity被其他Activity覆蓋其上,系統會調用onPause()方法,暫停當前Activity的執行,若用戶取消了覆蓋,系統會調用onResume()方法,重新進入到運行狀態。
  • Activity跳轉到了新的Activity界面或者被後臺了或者鎖屏時,系統會調用onPause();然後調用onStop();使Activity進入到停滯狀態,如果重新回到了該Activity界面(上一個Activity或者從後臺變爲了前臺時或者解開鎖屏時),系統會調用onRestart();再調用onStart();最後調用onResume()方法使該Activity進入到運行狀態
  • 當用戶退出Activity時會調用onPause();然後調用onStop();最後調用onDestory();結束Activity生命週期
  • 當Activity中彈出dialog對話框的時候,Activity不會調用onPause();只有當Activity啓動了dialog風格的Activity時纔會調用
  • 當Activity是由於異常情況下終止的,系統會調用onSaveInstance來保存當前Activity狀態,這個方法調用的時機是在onStop之前的,當Activity重新創建後,系統會調用onRestoreInstanceState,並且把Activity銷燬時的onSaveInstanceState方法保存的bundle對象作爲參數同時傳遞給onRestoreInstanceState和onCreate方法

Activity的四種啓動模式

Activity有四種啓動模式 standard,singleTop,singleTask,singleInstance,這四種模式我們可以在清單文件的<Activity節點下通過android:launchMode來進行配置

  • standard模式:在這種模式下,activity默認會進入啓動它的activity所屬的任務棧中。這也是默認的一種模式
  • singleTop模式:棧頂複用模式。如果新activity位於任務棧的棧頂的時候,activity不會被重新創建,同時它的onNewIntent方法會被回調。
  • singleTask模式:棧內複用模式。只要activity在一個棧中存在,那麼多次啓動此activity不會被重新創建單例,系統會回調onNewIntent。這種模式可以稱爲單例模式,只會存在一種,有則直接從棧中調用,沒有則創建並且壓入棧中
  • singleInstance模式:單實例模式。這種模式的activity只能單獨地位於一個任務棧中,這種與singleTask有點類似,其實也是有則直接調用,沒有則創建並且放入棧中,只不過singleTask是可以和其他的Activity放在同一個棧中,singleInstance則是隻會將創建的Activity放在一個棧中,並且這個棧中只會有這一個Activity實例

Service

Service分爲兩種,一種是Service(這一種是運行在主線程中的,如果要執行耗時操作,可在service中創建一個異步來執行),一種是IntentService(這是一種異步服務,是繼承於Service的子類),所以推薦當要執行耗時操作時使用IntentService,如果不耗時,我們可以使用Service

Service

Service的兩種啓動方式

  1. 通過start方法開啓服務
  • 創建一個類繼承Service
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

 

  • 在清單文件中註冊這個服務
   <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

 

  • 通過startService方法啓動服務
   Intent intent = new Intent(this, MyService.class);
   startService(intent);

 

  • 當不用服務的時候通過stopService()方法停止該服務
stopService(intent);

特點: 通過start方法啓動的service一旦服務開啓就跟調用者(開啓者)沒有任何關係了。開啓者退出了,開啓者掛了,服務還在後臺長期的運行,開啓者不能調用服務裏面的方法。

  1. 通過bind的方式啓動服務
  • 創建一個類繼承Service
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

 

  • 在清單文件中註冊這個服務
   <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

 

  • 通過startService方法啓動服務
   Intent intent = new Intent(this, MyService.class);
   bindService(Intent,ServiceConnection,int);

 

  • 當不用服務的時候通過stopService()方法停止該服務
unbindService(ServiceConnection);

 

特點:使用bind方法啓動的服務,則調用者掛了,服務也掛了,調用者可以調用服務中的方法

遠程服務

調用者與Service不在同一個進程,這是一種跨進程通信的方式Android綁定遠程服務

步驟:

  • 在服務的內部創建一個內部類,提供一個方法,可以間接調用服務的方法
  • 把暴露的接口文件的擴展名改爲.aidl文件 去掉訪問修飾符
  • 實現服務的onbind方法,繼承Bander和實現aidl定義的接口,提供給外界可調用的方法
  • 在activity 中綁定服務。bindService()
  • 在服務成功綁定的時候會回調 onServiceConnected方法 傳遞一個 IBinder對象
  • aidl定義的接口.Stub.asInterface(binder) 調用接口裏面的方法

IntentService

這個Service在上面也說過,是一個異步服務
IntentService特徵:

  • 會創建獨立的worker線程來處理所有的Intent請求;
  • 會創建獨立的worker線程來處理onHandleIntent()方法實現的代碼,無需處理多線程問題;
  • 所有請求處理完成後,IntentService會自動停止,無需調用stopSelf()方法停止Service;
  • 爲Service的onBind()提供默認實現,返回null;
  • 爲Service的onStartCommand提供默認實現,將請求Intent添加到隊列中;

BroadcastReceiver

廣播分爲兩種,一種是普通廣播,或者稱爲無序廣播,另一種是有序廣播

無序廣播與有序廣播

無序廣播是完全異步的,在同一時刻在邏輯上是能夠被所有的接收者接收到的,傳遞的效率高,缺點是接收者不能處理結果傳給下個接收者,並且無法終止廣播的傳播(其實有序廣播就是和這個相反的,有順序的傳播,兩個廣播的定義就是完全相反的,這個比較好記)

Context.sendBroadcast()
發送的是普通廣播,所有訂閱者都有機會獲得並進行處理。

 

廣播的生命週期就是在處理完onReceive時,系統將認定他不是一個活動的對象了,就是殺掉他,由於廣播的生命週期很短,所以不建議在onReceive中執行一些耗時操作

創建一個廣播的步驟:

  • 創建一個類繼承BroadcastReceiver,並且重寫其onReceive方法
public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("fuck","intent-action : " + intent.getAction());
        if(intent.getAction().equals("test")){
            Toast.makeText(context,"fuck",Toast.LENGTH_LONG).show();
        }
    }

}

 

  • 在清單文件中註冊(靜態註冊)

 

     //廣播接收器
        <receiver android:name=".broadcast.MyBroadcastReceiver">

            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="test"/>//這裏自定義一個廣播動作
            </intent-filter>

        </receiver>

 

或者動態註冊

 

registerReceiver(new MyBroadcastReceiver(),new IntentFilter("test"));

加上權限

 

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

 

  • 發送廣播
 Intent intent = new Intent("test");
 sendBroadcast(intent);

 

靜態註冊和動態註冊區別

動態註冊廣播不是常駐型廣播,也就是說廣播跟隨activity的生命週期。注意: 在activity結束前,移除廣播接收器。
靜態註冊是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。

  • 當廣播爲有序廣播時:
  1. 優先級高的先接收
  2. 同優先級的廣播接收器,動態優先於靜態
  3. 同優先級的同類廣播接收器,靜態:先掃描的優先於後掃描的,動態:先註冊的優先於後註冊的。
  • 當廣播爲普通廣播時:
  1. 無視優先級,動態廣播接收器優先於靜態廣播接收器
  2. 同優先級的同類廣播接收器,靜態:先掃描的優先於後掃描的,動態:先註冊的優先於後註冊的。

Service小結:

  • 在Android 中如果要發送一個廣播必須使用sendBroadCast 向系統發送對其感興趣的廣播接收器中。
  • 使用廣播必須要有一個intent 對象必設置其action動作對象
  • 使用廣播必須在配置文件中顯式的指明該廣播對象
  • 每次接收廣播都會重新生成一個接收廣播的對象
  • 在BroadCastReceiver中儘量不要處理太多邏輯問題,建議複雜的邏輯交給Activity 或者 Service 去處理
  • 如果在AndroidManifest.xml中註冊,當應用程序關閉的時候,也會接收到廣播。在應用程序中註冊就不產生這種情況了。

ContentProvider

contentprovider是android四大組件之一的內容提供器,它主要的作用就是將程序的內部的數據和外部進行共享,爲數據提供外部訪問接口,被訪問的數據主要以數據庫的形式存在,而且還可以選擇共享哪一部分的數據。這樣一來,對於程序當中的隱私數據可以不共享,從而更加安全。contentprovider是android中一種跨程序共享數據的重要組件。
自定義的內容提供者沒用過,因爲沒有實際的業務需求,系統的內容提供者用的比較多,所以具體也不知道該如何記錄ContentProvider

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章