[Android]任務列表中顯示"小程序"的原理分析

摘要: 談談微信是怎麼實如今任務列表中顯示"小程序"的.java

今天被小程序刷屏了^^ 我也來湊湊熱鬧.
談談微信是怎麼實如今任務列表中顯示"小程序"的.android

效果

微信中打開了"滴滴(小程序)"後,
能夠看到,任務列表不只顯示了"微信", 還顯示了"滴滴(小程序)"的人口.
經過這個入口,就能夠很方面的切換小程序了, 體驗和原生程序也同樣同樣的.docker

分析

下面簡單分析一下他的實現.shell

1.Android系統中,顯示最近程序列表的View是 RecentsPanelView.
他經過refreshRecentTasksList()加載程序列表,咱們來看看代碼:
能夠看到RecentTasksLoader mRecentTasksLoader負責真正處理數據加載.小程序

RecentsPanelView.java

private RecentTasksLoader mRecentTasksLoader; * * * private void refreshRecentTasksList( ArrayList<TaskDescription> recentTasksList, boolean firstScreenful) { if (mRecentTaskDescriptions == null && recentTasksList != null){ onTasksLoaded(recentTasksList, firstScreenful); } else { //加載最近的列表 mRecentTasksLoader.loadTasksInBackground(); } } 

2.順着看看RecentTasksLoader的實現:
這裏能夠清楚看到,加載的數據是ActivityManager.getRecentTasks()
也就是說顯示的是Task列表.bash

RecentTasksLoader.java

ArrayList<TaskDescription>  getRecentTasks() {
       cancelLoadingThumbnails();

       ArrayList<TaskDescription> tasks = new ArrayList<TaskDescription>(); final PackageManager pm = mContext.getPackageManager(); final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); //獲取最近的Task final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); * * * return tasks; } 

到這裏,已經很清楚了. 要顯示"小程序"入口, 只須要新建一個Task啓動就行了~
是否是很簡單啊.微信

來來來驗證一下咱們的想法.
這裏使用 adb shell dumpsys activity activities查看一下Task狀態工具

1. 只開啓微信

2. 開啓小程序

以下圖所示, 微信新開啓了一個.AppBrandUI的task棧
測試

實現

知道原理,實現就很簡單了.ui

假設小程序的Activity是 TaskTestActivity,整個實現分兩步:

1. AndroidManifest.xml中爲Activity設置taskAffinity
<activity
        android:icon="@drawable/didi" android:name=".TaskTestActivity" android:label="小程序測試" android:taskAffinity=".NewTask" /> 
2. 以NEW_TASK方式啓動Activity
//以Intent.FLAG_ACTIVITY_NEW_TASK方式啓動Activity Intent intent = new Intent(this, TaskTestActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 
爲何要設置taskAffinity呢,

這和FLAG_ACTIVITY_NEW_TASK的特性有關:

FLAG_ACTIVITY_NEW_TASK: 設置此狀態,首先會查找是否存在和被啓動的Activity具備相同的taskAffinity的task(注意同一個應用程序中默認全部activity 的taskAffinity是同樣的),若是有,剛直接把這個棧總體移動到前臺,並保持棧中的狀態不變,即棧中的activity順序不變,若是沒有,則新建一個棧來存放被啓動的activity.

也就是說,若是App已經啓動,即便用FLAG_ACTIVITY_NEW_TASK新起Activity, 由於taskAffinity相同,也會被壓到一個task中, 天然recent panel 就看不到兩個入口了.

因此咱們須要爲小程序設置一個新的taskAffinity

下面是demo效果

拓展

讓本身的程序不顯示在任務列表中

有時候咱們作一個工具, 或者後臺界面, 不但願顯示在程序列表中.
也很簡單,只要設置task的屬性就行了

方法1:

在AndroidManifest.xml設置Activity的 android:excludeFromRecents爲true

<activity
      android:excludeFromRecents="true" android:icon="@drawable/didi" android:name=".TaskTestActivity" android:label="小程序測試" /> 
方法2:

在啓動Activity的時候加上Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS FLAG

//Activity不顯示在recent列表中.
Intent intent = new Intent(this, TaskTestActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); startActivity(intent); 
本文爲雲棲社區原創內容,未經容許不得轉載,如需轉載請發送郵件至yqeditor@list.alibaba-inc.com;若是您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至:yqgroup@service.aliyun.com 進行舉報,並提供相關證據,一經查實,本社區將馬上刪除涉嫌侵權內容。
相關文章
相關標籤/搜索