Android launchMode 筆記---taskAffinity屬性和Intent標記體會

來源:互聯網
上載者:User

標籤:android   style   blog   class   code   java   

       launchmode的四種模式,不需要細說:standard、singleTop、singleTask、singleInstance。    此部落格關注的是,關於Activity中關於Affinity(親和力)&Intent標記的東西,即使是Android老鳥,也不一定將其中的細節理解透徹。使用Intent啟動一個Activity,有如下標記: 1、FLAG_ACTIVITY_NEW_TASK2、FLAG_ACTIVITY_CLEAR_TOP3、FLAG_ACTIVITY_RESET_TASK_IF_NEEDED4、FLAG_ACTIVITY_SINGLE_TOP 使用最多的,當然是FLAG_ACTIVITY_NEW_TASK。主要的Activity屬性有:1、taskAffinity2、launchMode3、allowTaskReparenting4、clearTaskOnLaunch5、alwaysRetainTaskState6、finishOnTaskLaunch      當Affinity與LaunchMode結合起來使用,就比較讓人蛋疼的事情了。在實際項目中,靈活使用各種屬性,可以讓程式運行流暢,介面直接的導航跳轉流暢,使用者體驗良好。反之,則讓人摸不著頭腦,讓人蛋疼。絕知此事須躬行的道理,才油然而生。關於上述的各種屬性,可以參看Google文檔,Tasks and Back Stack ,文檔中將各種情況分析得較為全面,網上的資料,均是翻譯其內容。 FLAG_ACTIVITY_NEW_TASK 講解:case 1:當Intent對象包含這個標記時,系統會尋找或建立一個新的task來放置目標Activity,尋找時依據目標Activity的taskAffinity屬性進行匹配,如果找到一個task的taskAffinity與之相同,就將目標Activity壓入此task中。case 2:如果尋找無果,則建立一個新的task,並將該task的taskAffinity設定為目標Activity的taskActivity,將目標Activity放置於此task。上面的兩個case,可以簡單的理解為:FLAG_ACTIVITY_NEW_TASK標記,不一定會啟動一個新的棧,其策略是:先尋找有沒有和這個Activity的affinity相同的task棧,如果有,則直接在這個task棧裡啟動,沒有才建立一個新的task棧。case 3:如果同一個應用中Activity的taskAffinity都使用預設值或都設定相同值時,應用內的Activity之間的跳轉使用這個標記是沒有意義的,因為當前應用task就是目標Activity最好的宿主。為了更好的說明其中的扯淡關係,使用案例進行說明上述的case 1、case 2、case 3一個簡單的app中,MainActivity點擊按鈕啟動一個新的Activity。
  
case 1:在AndroidManifest.xml中定義的屬性為:
        <activity            android:name="com.coder80.appother.MainActivity"            android:label="AppOther MainActivity" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>       ... .... .... ....         <activity            android:name="com.coder80.appother.OtherActivity"            android:label="AppOther OtherActivity"            >        </activity>
app運行效果如下:
    
在OtherActivity介面,多次點擊“Start AppOther OtherActivity in AppOther”按鈕,會啟動多個Activity Instance,由於兩個Activity擁有共同的taskAffinity,將處於同一個task裡面。
case 2:在AndroidManifest.xml中定義的屬性為:
<activity    android:name="com.coder80.appother.MainActivity"    android:label="AppOther MainActivity" >    <intent-filter>        <action android:name="android.intent.action.MAIN" />        <category android:name="android.intent.category.LAUNCHER" />    </intent-filter></activity><activity    android:name="com.coder80.appother.OtherActivity"    android:label="AppOther OtherActivity"     android:taskAffinity="com.xxxx"    ></activity>
app運行效果如下:
 
在OtherActivity介面,點擊“Start AppOther OtherActivity in AppOther”按鈕,建立新的Activity Instance,由於兩個Activity擁有的taskAffinity不同,新的instant將處於另外的task裡面,其task id 為23.
PS:此處多次點擊點擊“Start AppOther OtherActivity in AppOther”按鈕,不會產生新的Activity Instance
           在case 2中,當介面停留在OtherActivity時,此時按Home鍵,讓app進入後台運行,再次啟動app,將直接顯示MainActivity介面,而不是OtherActivity介面。主要原因是,該app的啟動時,系統將尋找root Activity所處的那個task,而該app的root activity為MainActivity,所以顯示MainActivity介面。
case 3:在AndroidManifest.xml中定義的屬性為與case 1一致。
    此時Activity之間的導航,與普通的跳轉一致,task的建立與否,直接根據launchMode來確定。
allowTaskReparenting講解
      這個屬性用來標記一個Activity執行個體在當前應用退居後台後,是否能從啟動它的那個task移動到有共同affinity的task,“true”表示可以移動,“false”表示它必須呆在當前應用的task中,預設值為false。
      如果一個Activity的<activity>元素沒有設定此屬性,則為預設。繼續用demo進行示範,進行深入淺出的分析。
      應用TaskAffinity的MainActivity中,點擊按鈕,進入應用AppOther的OtherActivity,其對應AndroidManifest.xml中定義的屬性如下:
      TaskAffinity的AndroidManifest.xml
    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.coder80.taskaffinity.MainActivity"            android:label="TaskAffinity MainActivity" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>

AppOther的AndroidManifest.xml
        <activity            android:name="com.coder80.appother.OtherActivity"            android:label="AppOther OtherActivity"             >            <intent-filter>                <action android:name="android.intent.action.AppOther_OTHER_ACTIVITY" />                <category android:name="android.intent.category.DEFAULT"/>            </intent-filter>        </activity>
    首先運行TaskAffinity應用,啟動介面如下:
  點擊“Start AppOther OtherActivity”按鈕,執行如下的代碼:
Intent intent = new Intent("android.intent.action.AppOther_OTHER_ACTIVITY");  startActivity(intent); 
將啟動AppOther中的OtherActivity介面,效果如下:
  兩個Activity的task id 一致,表明是在同一個task裡面。此時,按下“Home”鍵,顯示主屏,之後再菜單中點擊TaskAffinity應用表徵圖,啟動之後,介面如下:
  依舊顯示的是AppOther應用的OtherActivity介面。
    由此demo,瞭解到,不同應用的Activity,可以處於同一個task裡面,並且使用預設的allowTaskReparenting屬性,其task在由後台轉入前台時,不會從task remove。
    樣本將做小小改動,修改AppOther中OtherActivity的屬性,將allowTaskReparenting置為true,其他的代碼,不做任何修改,AndroidManifest.xml如下:
        <activity            android:name="com.coder80.appother.OtherActivity"            android:label="AppOther OtherActivity"             android:allowTaskReparenting="true"            >            <intent-filter>                <action android:name="android.intent.action.AppOther_OTHER_ACTIVITY" />                <category android:name="android.intent.category.DEFAULT"/>            </intent-filter>        </activity>
運行後,如下:
   TaskAffinity應用圖                  點擊按鈕,啟動OtherActivity圖  按下home鍵後,再次TaskAffinity圖
    
 從上述樣本,可以得知,android:allowTaskReparenting="true",對於Activity的作用了。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.