# Android中的任务和返回栈总结
2016-06-17 16:31
609 查看
Android中的任务和返回栈
任务栈的基础知识:
任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即“返回栈”)中。为什么要用任务栈:
为了记录用户开启了那些activity,记录这些activity开启的先后顺序,google引入任务栈(task stack)概念,帮助维护好的用户体验。如何查看当前系统的任务栈
手机中 –> 长按home或者多任务键会进到 概览屏幕 的一个界面命令行中 –> adb shell dumpsys activity
基础点关于 Activiy启动模式
在AndroidMainifest.xml文件里面的activity标签设置启动模,简单实例如下:。<activity android:name=".FirstActivity" android:launchMode="singleTop" android:label="This is FirstActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
standard,标准模式,每次都会创建新的Activity覆盖在原Activity上。
singleTop,栈顶复用模式,首先判断栈顶Activity是否是要启动的Activity,如果是则不创建新的Activity而直接引用这个Activity;如果不是则创建新的Activity。
singleTask,栈内复用模式,检测整个Activity栈中是否存在当前需要启动的Activity,如果存在则将该Activity置于栈顶,并销毁其上所有Activity。
singleInstance,单实例模式,创建新的任务栈,且该任务栈仅有一个Activity。
通过TaskAffinity 设置新的任务栈:
taskAffinity,任务相关性。xml中的一个属性,标识了一个Activity所需要的任务栈的名字。默认是包名。如果设置了其他的名字如com.test.task1,那启动它的时候就会新建一个名为com.test.task1的任务栈。<activity android:name="com.test.task0.MainActivity" android:label="@string/app_name" android:launchMode="standard"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category andorid:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity andorid:name="com.test.SecondActivity" android:taskAffinity="com.test.task1" android:label="@string/app_name" android:launchMode="singleTask"/> <activity andorid:name="com.test.ThirdActivity" android:taskAffinity="com.test.task1" android:label="@string/app_name" android:launchMode="singleTask"/>
如果从MainActivity启动SecondActivity,然后再启动ThirdActivity,那么任务栈如下:
Blockquotes com.test.task0 MainActivity
Blockquotes com.test.task1 SecondActivity ThirdActivity
若再从ThirdActivity启动MainActivity,那么任务栈如下:
com.test.task0 MainActivity
com.test.task1 SecondActivity ThirdActivity MainActivity.
总结:通过设置 TaskAffinity 属性更改任务栈属性。
回退栈和通知
通过通知进入Activity存在的问题
默认情况下,从通知启动一个Activity,按返回键会回到主屏幕。但某些时候有按返回键仍然留在当前应用的需求。从通知打开的某个深层次Activity。在此Acitivity中点回退,若不做处理,将会直接返回到AndroidLaunch界面。这是因为在Notification中的PendingIntent会默认开启新的任务栈。当回退的时候此任务栈没有其他新的Activity,默认在PendingIntent 的Activity是任务栈中唯一的 Activity.举例: HomeActiy=>Step1Activity=>Step2Acitity
某个通知 默认在PendingIntent 指定了Step2Acitity。通过通知栏进入到Step2Acitity。点回退。正常的顺序为:
Step2Activity=>Step1Acitivity=>HomeActivity但是如果通过通知栏这样进入Step2Activity 点回退 会直接退回到Android 桌面。就是因为 PendingIntent会默认开启新的任务栈
解决方法:
通过TaskStackBuilder设置具体的回退路径:在 AndroidManifest.xml定义Acitivity从属关系。
Android 4.0.3 及更早版本 <activity android:name=".ResultActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"/> </activity> Android 4.1 及更高版本 <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity"> </activity>
代码中做如下处理 Intent intent = new Intent(MainActivity.this, ResultActivity.class); TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this); taskStackBuilder.addParentStack(ResultActivity.class); taskStackBuilder.addNextIntent(intent); PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this); notificationBuilder.setContentIntent(pendingIntent);
这样从Notification进入到指定的ResultActivity中。回退到正常的MainActivity中。
TaskStackBuilder 扩展应用
也可以单独使用TaskStackBuilder,让某个二级Acitivity启动的时候启动它的一级Acitity.在 AndroidManifest.xml定义Acitivity从属关系。
<activity android:name="com.example.app.ChildActivity android:parentActivityName="com.example.app.ParentActivity" > <!-- 下面这段用来兼容API 16之前的版本 --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app.MainActivity" /> </activity>
//代码中声明如下 Intent intent = new Intent(this, ChildActivity.class); TaskStackBuilder.create(this) .addNextIntentWithParentStack(intent) .startActivities();
通过启动一个无任何层级关系的Acitity 激活应用(目前Lianlian3.0应用采用此方法)
public class SimpleLaunchAppActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Now finish, which will drop the user in to the activity that was at the top // of the task stack finish(); } }
原理:若通过Notification打开Acitivity后此Acitivy会位于要启动的App的栈顶。自动finish()后,app恢复到切换到后台之前的状态。SimpleLaunchAppActivity不得设置android:taskAffinity。taskAffinity和默认App的包名一致就不会新建任务栈。若设置了taskAffinity为新的任务栈,点回退后 将会回到android launch页面。
联连wifi的解决方案:
通过启动一个无任何层级关系的TransparentSwitchActivity 激活应用**目前存在的问题是TransparentSwitchActivity里面会根据参数判断 通过通知进入后还有部分逻辑不太人性化和完善。需要提高用户体验。
关于系统默认的清空返回栈
如何用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。当然,既然说是默认的行为,那就说明我们肯定是有办法来改变的,在Manifest中 元素中设置以下几种属性就可以改变系统这一默认行为:alwaysRetainTaskState
如果将最底层的那个Activity的这个属性设置为true,那么上面所描述的默认行为就将不会发生,任务中所有的Activity即使过了很长一段时间之后仍然会被继续保留。
clearTaskOnLaunch
如果将最底层的那个Activity的这个属性设置为true,那么只要用户离开了当前任务,再次返回的时候就会将最底层Activity之上的所有其它Activity全部清除掉。简单来讲,就是一种和alwaysRetainTaskState完全相反的工作模式,它保证每次返回任务的时候都会是一种初始化状态,即使用户仅仅离开了很短的一段时间。
finishOnTaskLaunch
这个属性和clearTaskOnLaunch是比较类似的,不过它不是作用于整个任务上的,而是作用于单个Activity上。如果某个Activity将这个属性设置成true,那么用户一旦离开了当前任务,再次返回时这个Activity就会被清除掉。
1:参考:Notification to restore a task rather than a specific activity?
2:参考:启动一个Activity时让指定父页面同时启动并处于它的下方
3:参考: Activity与Activity调用栈
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories