Android四大組件之Activity

Acitivity作爲Android四大組件之首,在Android app開發過程當中尤其重要,這裏咱們對Activity的生命週期啓動模式 Flags 異常退出的狀態保存狀態恢復顯式啓動隱式啓動以及Activity的隱式啓動action category data的過濾規則整理總結。java

Activity的生命週期

activity_life_cycle.png

分別覆寫Activity生命週期中幾個重要的方法:android

protected void onCreate(Bundle savedInstanceState) {
        Log.i("target","Activity onCreate");
    }
    protected void onStart() {
        Log.i("target","Activity onStart");
    }
    protected void onRestart() {
        Log.i("target","Activity onRestart");
    }
    protected void onResume() {
        Log.i("target","Activity onResume");
    }
    protected void onPause() {
        Log.i("target","Activity onPause");
    }
    protected void onStop() {
        Log.i("target","Activity onStop");
    }
    protected void onDestroy() {
        Log.i("target","Activity onDestroy");
    }
不一樣情境下生命週期方法執行順序

正常狀況下生命週期
從進入activity到按下回退鍵退出activity瀏覽器

com.example.root.activitylifecycle I/target: Activity onCreate
com.example.root.activitylifecycle I/target: Activity onStart
com.example.root.activitylifecycle I/target: Activity onResume
com.example.root.activitylifecycle I/target: Activity onPause
com.example.root.activitylifecycle I/target: Activity onStop
com.example.root.activitylifecycle I/target: Activity onDestroy

屏幕滅掉app

com.example.root.activitylifecycle I/target: Activity onCreate
com.example.root.activitylifecycle I/target: Activity onStart
com.example.root.activitylifecycle I/target: Activity onResume
com.example.root.activitylifecycle I/target: Activity onPause
com.example.root.activitylifecycle I/target: Activity onStop

能夠看到並無執行onDestroy方法,接下來點亮屏幕ide

com.example.root.activitylifecycle I/target: Activity onRestart
com.example.root.activitylifecycle I/target: Activity onStart
com.example.root.activitylifecycle I/target: Activity onResume

跳轉到其餘activitythis

com.example.root.activitylifecycle I/target: Activity onCreate
com.example.root.activitylifecycle I/target: Activity onStart
com.example.root.activitylifecycle I/target: Activity onResume
com.example.root.activitylifecycle I/target: Activity onPause
com.example.root.activitylifecycle I/target: SecondActivity onCreate
com.example.root.activitylifecycle I/target: SecondActivity onStart
com.example.root.activitylifecycle I/target: SecondActivity onResume
com.example.root.activitylifecycle I/target: Activity onStop

注意:當第二個activity執行到onResume方法後第一個activity才執行onStop方法,即當第二個activity就緒以後第一個activity才執行onStop方法,但第一個activity並無執行onDestroy方法,它被放入後退棧中。
接下來按下退格鍵返回第一個activityspa

com.example.root.activitylifecycle I/target: SecondActivity onPause
com.example.root.activitylifecycle I/target: Activity onRestart
com.example.root.activitylifecycle I/target: Activity onStart
com.example.root.activitylifecycle I/target: Activity onResume
com.example.root.activitylifecycle I/target: SecondActivity onStop
com.example.root.activitylifecycle I/target: SecondActivity onDestroy

第二個activity的生命週期執行完成,第一個activity執行onRestartonResume從新就緒,再次按下退格鍵日誌

com.example.root.activitylifecycle I/target: Activity onPause
com.example.root.activitylifecycle I/target: SecondActivity onStop
com.example.root.activitylifecycle I/target: SecondActivity onDestroy

第一個activity生命週期執行結束code

Activity異常時數據保存於數據恢復

當屏幕旋轉的時候activity就會從新執行onCreate,咱們能夠用屏幕旋轉模擬activity異常銷燬生命週期

protected void onSaveInstanceState(Bundle outState) {
        Log.i("target","Activity onSaveInstanceState");
        outState.putString("target","this is onSaveInstanceState saved bundle data");
    }
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        Log.i("target","Activity onRestoreInstanceState");
        Log.i("target",savedInstanceState.getString("target"));
    }

日誌信息

com.example.root.activitylifecycle I/target: Activity onSaveInstanceState
com.example.root.activitylifecycle I/target: Activity onRestoreInstanceState
com.example.root.activitylifecycle I/target: this is onSaveInstanceState saved bundle data
Activity的LaunchMode
  • standard模式:這是默認模式,每次激活Activity時都會建立Activity實例,並放入任務棧中,使用場景(大多數Activity)

  • singleTop模式:若是任務棧的棧頂正好存在該Activity的實例,就重用該實例(會調用實例的onNewIntent()),不然就會建立新的實例並放入棧頂,計時棧中已經存在該Activity的實例,只要不在棧頂,都會建立新的實例,使用場景(新聞類或者閱讀類App的內容頁面)

  • singleTask模式:若是棧中已經有該Activity的實例,就重寫該實例(會調用實例的onNewIntent())。重用時,會讓該實例回到棧頂,所以在他上面的實例將會被移出棧,若是棧中不存在該實例,將建立新的實例放入棧中,使用場景如瀏覽器的主界面,無論從多少個應用啓動瀏覽器,只會啓動主界面一次,其他都會走onNewIntent,並清空主界面上的其餘頁面

  • singleInstance模式:在一個新棧中建立該Activity的實例,並讓多個應用共享該棧中的該activity實例,一旦該模式的activity實例已經存在於某個棧中,任何英語再激活該activity時都會重用該棧中的實例,會調用(onNewIntent()),其效果至關於多個應用共享一個應用,無論誰激活該activity都會進入同一個應用中,使用場景(鬧鈴提示,將鬧鐘提醒與鬧鐘設置分離),singleinstance不要敢於中間頁面,若是用於中間頁面,跳轉會有問題(A->B->(singleinstance)->C)徹底退出後再次啓動首先打開的是B

Activity的Flags

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//指定Activity爲"singleTask"啓動模式
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//指定Activity爲"singleTop"啓動模式
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//位於其上的Activity都要出棧,相似"singleTask"
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);//不會出如今Activity的歷史列表中,等同於android:excludeFromRecents="true"

IntentFilter的匹配規則

爲了匹配過濾列表,須要同時匹配過濾列表中的action,category,data信息。一個Activity能夠有多個intentFilter,一個Intent只要能匹配任何一組intentFilter便可成功啓動對應Activity

action的匹配規則

action區分大小寫,必須存在,只需匹配一個
category的匹配規則能夠沒有,如果有,必須所有匹配(能夠比過濾規則中少)
示例:

<intent-filter>
    <action android:name="com.example.root.saveinstancelearn.secondactivity"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="com.example.root.saveinstancelearn.secondactivity"/>
</intent-filter>
Intent intent=new Intent("com.example.root.saveinstancelearn.secondactivity");               
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
data的匹配規則

data與action相似(data語法以下)

<data android:scheme="string"
    android:host="string"
    android:port="string"
    android:path="string"
    android:pathPattern="string"
    android:pathPrefix="string"
    android:mimeType="string" />

data有兩部分組成,mimeType和URI。mimeType指定媒體類型,好比image/jpeg等
匹配示例:

<intent-filter>
    <data android:mimeType="image/*"/>
<intent-filter>

intent.setDataAndType(Uri.parse("file://abc"),"image/png");

ps:若是要爲Intent指定完整的data,必須調用setDataAndType方法,不能先調用setData在調用setType,覺得這兩個方法會清除對方的值;

實例

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http"/>
    <data android:mimeType="audio/mpeg" android:scheme="http"/>
</intent-filter>

intent.setDataAndType(Uri.parse("http://abc"),"video/mpeg");或者
intent.setDataAndType(Uri.parse("http://abc"),"audio/mpeg");

更多關於java的文章請戳這裏:(您的留言意見是對我最大的支持)

個人文章列表

Email:sxh13208803520@gmail.com

相關文章
相關標籤/搜索