摘要:谈谈微信是怎么实现在任务列表中显示"小程序"的.
今天被小程序刷屏了^^ 我也来凑凑热闹.
谈谈微信是怎么实现在任务列表中显示"小程序"的.
效果
微信中打开了"滴滴(小程序)"后,
可以看到,任务列表不仅显示了"微信", 还显示了"滴滴(小程序)"的人口.
通过这个入口,就可以很方面的切换小程序了, 体验和原生程序也一样一样的.
![](http://img.e-com-net.com/image/info10/026de9fef8e04dc59d90ae52eba7e644.jpg)
分析
下面简单分析一下他的实现.
1.Android系统中,显示最近程序列表的View是RecentsPanelView.
他通过refreshRecentTasksList()加载程序列表,我们来看看代码:
可以看到RecentTasksLoader mRecentTasksLoader负责真正处理数据加载.
RecentsPanelView.java
privateRecentTasksLoader mRecentTasksLoader; * * *privatevoidrefreshRecentTasksList( ArrayList recentTasksList,booleanfirstScreenful){if(mRecentTaskDescriptions ==null&& recentTasksList !=null){ onTasksLoaded(recentTasksList, firstScreenful); }else{//加载最近的列表mRecentTasksLoader.loadTasksInBackground(); } }
2.顺着看看RecentTasksLoader的实现:
这里可以清楚看到,加载的数据是ActivityManager.getRecentTasks().
也就是说显示的是Task列表.
RecentTasksLoader.java
ArrayList getRecentTasks() { cancelLoadingThumbnails(); ArrayList tasks =newArrayList();finalPackageManager pm = mContext.getPackageManager();finalActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);//获取最近的TaskfinalList recentTasks = am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); * * *returntasks; }
到这里,已经很清楚了. 要显示"小程序"入口, 只需要新建一个Task启动就好了~
是不是很简单啊.
来来来验证一下我们的想法.
这里使用adb shell dumpsys activity activities查看一下Task状态
1. 只开启微信
![](http://img.e-com-net.com/image/info10/fab34ba4b36544258f87fbd9487a7f89.jpg)
2. 开启小程序
如下图所示, 微信新开启了一个.AppBrandUI的task栈
![](http://img.e-com-net.com/image/info10/ef4d63ccba6d4e108c67f4ee930cb636.jpg)
实现
知道原理,实现就很简单了.
假设小程序的Activity是 TaskTestActivity,整个实现分两步:
1. AndroidManifest.xml中为Activity设置taskAffinity
2. 以NEW_TASK方式启动Activity
//以Intent.FLAG_ACTIVITY_NEW_TASK方式启动ActivityIntentintent= newIntent(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效果
![](http://img.e-com-net.com/image/info10/3bd3907d27294a238f3c03ffa1641b47.jpg)
拓展
让自己的程序不显示在任务列表中
有时候我们做一个工具, 或者后台界面, 不希望显示在程序列表中.
也很简单,只要设置task的属性就好了
方法1:
在AndroidManifest.xml设置Activity的android:excludeFromRecents为true
方法2:
在启动Activity的时候加上Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTSFLAG
//Activity不显示在recent列表中.Intentintent= newIntent(this, TaskTestActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);startActivity(intent);
本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至[email protected];如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:[email protected] 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。