Android開發(fā)小知識(shí)4—深度探索Activity

前言

Android四大組件有Activity、service、Content Provider、BroadcastReceiver。Activity是Android組件中最基本也是最為常見用的四大組件之一,其重要程度可想而知。對(duì)于大部分Android開發(fā)者來說,都可以輕松的使用它。但是在這篇文章中,我想深入的探索Activity。從而更好的從事開發(fā)工作。

概念

Activity是一個(gè)應(yīng)用組件,用戶可與其提供的屏幕進(jìn)行交互,以執(zhí)行撥打電話、拍攝照片、發(fā)送電子郵件或查看地圖等操作。 每個(gè) Activity 都會(huì)獲得一個(gè)用于繪制其用戶界面的窗口。窗口通常會(huì)充滿屏幕,但也可小于屏幕并浮動(dòng)在其他窗口之上。

Activity 基本上以三種狀態(tài)存在:

狀態(tài) 描述
繼續(xù) 此 Activity 位于屏幕前臺(tái)并具有用戶焦點(diǎn)。(有時(shí)也將此狀態(tài)稱作“運(yùn)行中”。)
暫停 另一個(gè) Activity 位于屏幕前臺(tái)并具有用戶焦點(diǎn),但此 Activity 仍可見。也就是說,另一個(gè) Activity 顯示在此 Activity 上方,并且該 Activity 部分透明或未覆蓋整個(gè)屏幕。 暫停的 Activity 處于完全活動(dòng)狀態(tài)Activity對(duì)象保留在內(nèi)存中,它保留了所有狀態(tài)和成員信息,并與窗口管理器保持連接),但在內(nèi)存極度不足的情況下,可能會(huì)被系統(tǒng)終止。
停止 該 Activity 被另一個(gè) Activity 完全遮蓋(該 Activity 目前位于“后臺(tái)”)。 已停止的 Activity 同樣仍處于活動(dòng)狀態(tài)(Activity對(duì)象保留在內(nèi)存中,它保留了所有狀態(tài)和成員信息,但未與窗口管理器連接)。 不過,它對(duì)用戶不再可見,在他處需要內(nèi)存時(shí)可能會(huì)被系統(tǒng)終止。

如果 Activity 處于暫?;蛲V?fàn)顟B(tài),系統(tǒng)可通過要求其結(jié)束(調(diào)用 finish()
方法)或直接終止其進(jìn)程,將其從內(nèi)存中刪除。(將其結(jié)束或終止后)再次打開 Activity 時(shí),必須重建。

生命周期

Activity生命周期切換過程(圖片來自網(wǎng)絡(luò))

這是一張經(jīng)典的Activity生命周期圖,詳細(xì)而直觀得表現(xiàn)了Activity各生命周期間的關(guān)系 。那么下圖 列出了相同的生命周期回調(diào)方法,其中對(duì)每一種回調(diào)方法做了更詳細(xì)的描述,并說明了每一種方法在 Activity 整個(gè)生命周期內(nèi)的位置,包括在回調(diào)方法完成后系統(tǒng)能否終止 Activity。

生命周期回調(diào)方法的描述.png

這些方法共同定義 Activity 的整個(gè)生命周期。您可以通過實(shí)現(xiàn)這些方法監(jiān)控 Activity 生命周期中的三個(gè)嵌套循環(huán):

  • Activity 的整個(gè)生命周期發(fā)生在onCreate()調(diào)用與onDestroy()調(diào)用之間。Activity 應(yīng)在onCreate()中執(zhí)行“全局”狀態(tài)設(shè)置(例如初始化View);在onDestroy()中釋放資源(例如調(diào)用unregisterReceiver)。

  • Activity 的可見生命周期發(fā)生在onStart()調(diào)用與onStop()調(diào)用之間。在這段時(shí)間,用戶可以在屏幕上看到 Activity 并與其交互。 在 Activity 的整個(gè)生命周期,當(dāng) Activity 在對(duì)用戶可見和隱藏兩種狀態(tài)中交替變化時(shí),系統(tǒng)可能會(huì)多次調(diào)用onStart()onStop()。

  • Activity 的前臺(tái)生命周期發(fā)生在onResume()調(diào)用與onPause()調(diào)用之間。在這段時(shí)間,Activity 位于屏幕上的所有其他 Activity 之前,并具有用戶輸入焦點(diǎn)。 Activity 可頻繁轉(zhuǎn)入和轉(zhuǎn)出前臺(tái)。由于此狀態(tài)可能經(jīng)常發(fā)生轉(zhuǎn)變,因此這兩個(gè)方法中應(yīng)采用適度輕量級(jí)的代碼,以避免因轉(zhuǎn)變速度慢而讓用戶等待。

啟動(dòng)方式

Activity的啟動(dòng)方式有兩種方式:顯示調(diào)用隱式調(diào)用。靈活的運(yùn)用這兩種能使您的APP更加方便快捷,提高用戶體驗(yàn)。

顯示調(diào)用

顯示調(diào)用:通過指定組件名稱來實(shí)現(xiàn)的,它一般用在知道目標(biāo)組件名稱的前提下,一般是在相同的應(yīng)用程序內(nèi)部實(shí)現(xiàn)的。

直接啟動(dòng)Activity
//通過Activity名啟動(dòng)
Intent intent=new Intent(MainActivity.this,SettingActivity.class);
intent.putExtra(NAME,nameText);
startActivity(intent);

//通過包名和Activity名啟動(dòng)
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName componentName = new ComponentName("com.zxm.demo","com.zxm.demo.MainActivity");
intent.setComponent(componentName );
startActivity(intent);
啟動(dòng)Activity以獲取結(jié)果
private void pickContact() {
    Intent intent = new Intent(OneActivity.this,SecondActivity.class);
    startActivityForResult(intent, REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
      //Data received: data.getData()
    }
}

隱式調(diào)用

隱式調(diào)用:通過Intent Filter來實(shí)現(xiàn)的,Android系統(tǒng)會(huì)根據(jù)隱式意圖中設(shè)置的動(dòng)作(action)、類別(category)、數(shù)據(jù)(URI和數(shù)據(jù)類型)找到最合適的組件來處理這個(gè)意圖。一般是用于在不同應(yīng)用程序之間。

設(shè)置數(shù)據(jù)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
Uri uri = Uri.parse(Uri.parser("host//:scheme?param"));
intent.setData(uri);
activity.startActivity(intent);

對(duì)應(yīng)的AndroidManifest.xml中的IntentFilter添加相應(yīng)的配置

<activity
            android:name="com.zxm.demo.SecondActivity"
             android:label="@string/app_name"  >
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:host="host"
                    android:scheme="scheme" />
            </intent-filter>
</activity>
設(shè)置類別

如果Intent中的存在category那么所有的category都必須和Activity過濾規(guī)則中的category相同。才能和這個(gè)Activity匹配。Intent中的category數(shù)量可能少于Activity中配置的category數(shù)量,但是Intent中的這category必須和Activity中配置的category相同才能匹配。這里注意,值設(shè)置類別是不能啟動(dòng)成功的,必須要

Intent intent = new Intent();
intent.addCategory("com.zxm.category.type_1");
intent.setAction("android.intent.action.SEND");  
startActivity(intent);  

對(duì)應(yīng)的AndroidManifest.xml中的IntentFilter添加相應(yīng)的配置

<activity
          android:name="com.zxm.demo.MainActivity"
          android:label="@string/app_name" >
          <intent-filter>
              <category android:name="android.intent.action.SEND" />
              <category android:name="com.zxm.category.type_1" />
              <category android:name="android.intent.category.DEFAULT" />
          </intent-filter>
</activity>
設(shè)置動(dòng)作

Intent中的Action必須能夠和Activity過濾規(guī)則中的Action匹配.(這里的匹配是完全相等). 一個(gè)過濾規(guī)則中有多個(gè)action,那么只要Intent中的action能夠和Activity過濾規(guī)則中的任何一個(gè)action相同即可匹配成功。

Intent intent = new Intent();  
//設(shè)置Intent的Action屬性  
intent.setAction("android.intent.action.SEND");  
startActivity(intent);  
<activity
          android:name="com.zxm.demo.MainActivity"
          android:label="@string/app_name" >
          <intent-filter>
              <category android:name="android.intent.action.SEND" />
              <category android:name="android.intent.category.DEFAULT" />
          </intent-filter>
</activity>

啟動(dòng)模式(LaunchMode)

Activity的啟動(dòng)模式有四種:standard、singleTop、singleTask、singleInstance。
想搞清楚啟動(dòng)模式,首先我們要搞清楚什么是任務(wù)棧(TaskAffinity)。

TaskAffinity 參數(shù)標(biāo)識(shí)著Activity所需要的任務(wù)棧的名稱,默認(rèn)情況下,一個(gè)應(yīng)用中所有Activity所需要的任務(wù)棧名稱都為該應(yīng)用的包名。

TaskAffinity 屬性一般跟singleTask模式或者跟allowTaskReparenting屬性結(jié)合使用,在其他情況下沒有實(shí)際意義。

  • standard:標(biāo)準(zhǔn)模式,這是系統(tǒng)默認(rèn)的默認(rèn)。在這種模式下不管之前有沒有Activity實(shí)例,每一次啟動(dòng)Activity都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例,并置于Activity任務(wù)棧棧頂。

  • singleTop:棧頂復(fù)用模式。這個(gè)模式下,如果棧頂存在該Activity的實(shí)例,那么這個(gè)Activity不會(huì)被重寫創(chuàng)建,同時(shí)它的onNewIntent()方法會(huì)被調(diào)用。如果棧頂不存在該Activity的實(shí)例,則情況與standard模式相同。注意的如果Activity已經(jīng)存在它的onCreate(),onStart()方法不會(huì)被調(diào)用。

  • singleTask:棧內(nèi)復(fù)用模式。在這種模式下,只要Activity存在棧內(nèi),那么多次啟動(dòng)這個(gè)Activity都不會(huì)重新創(chuàng)建實(shí)例,直接使用這個(gè)實(shí)例,并且將該實(shí)例以上的Activity全部清除,同時(shí)系統(tǒng)會(huì)調(diào)用它的onNewIntent()方法。

  • singleInstance:全局唯一模式, 該模式具備singleTask模式的所有特性外,與它的區(qū)別就是,這種模式下的Activity會(huì)單獨(dú)占用一個(gè)Task棧,具有全局唯一性。如果在啟動(dòng)這樣的Activiyt時(shí),已經(jīng)存在了一個(gè)實(shí)例,那么會(huì)把它所在的任務(wù)調(diào)度到前臺(tái),重用這個(gè)實(shí)例。

小結(jié)

關(guān)于Activity的知識(shí)還有很多,相信大家如果弄懂了以上這些點(diǎn),會(huì)跟好的把握和掌控項(xiàng)目。文章參考了AndroidAPI指南。 如有不足之處,希望多多指出。

原文作者litterMay
原文鏈接:http://m.itdecent.cn/p/e2ba919a2c56

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容