- 任务
任务是指执行特定作业时与用户交互的一系列Activity,这些Activity按照各自的打开顺序排列在堆栈
(即“返回栈”)中。google为了记录用户开启了那些Activity,引入了 任务栈(task stack) 的概念,
用于记录activity开启的先后顺序,帮助维护好的用户体验。栈的特性是:先进后出。 - 如何查看当前系统的任务栈
- 手机中,长按 home或者多任务键 会进入到概览屏幕的一个界面;
- 命令行中,adb shell dumpsys activity;
Activity启动模式
Activity启动模式在AndroidMainifest.xml文件里面的activity标签设置,属性名为android:launchMode,示例如下:1
2
3
4
5
6
7
8
9<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,如果不存在则创建新的Activity置于栈顶。 - singleInstance:单实例模式,创建新的任务栈,且该任务栈仅有一个Activity。
- standard:标准模式,也是系统默认的,每次都会创建新的Activity覆盖在原Activity上。
其他
- 为Activity设置新的任务栈
taskAffinity,任务相关性。xml中的一个属性,标识了一个Activity所需要的任务栈的名字。默认是包名。如果设置了其他的名字如com.test.task1,那启动它的时候就会新建一个名为com.test.task1的任务栈。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<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 MainActivit
总结:通过设置 TaskAffinity 属性更改任务栈属性。1
2- 回退栈和通知
通过通知进入Activity存在的问题,默认情况下,从通知启动一个Activity,按返回键会回到主屏幕。但某些时候有按返回键仍然留在当前应用的需求。从通知打开的某个深层次Activity。在此Acitivity中点回退,若不做处理,将会直接返回到AndroidLaunch界面。这是因为在Notification中的PendingIntent会默认开启新的任务栈。当回退的时候此任务栈没有其他新的Activity,默认在PendingIntent 的Activity是任务栈中唯一的 Activity.举例: HomeActiy=>Step1Activity=>Step2Acitity
某个通知 默认在PendingIntent 指定了Step2Acitity。通过通知栏进入到Step2Acitity。点回退。正常的顺序为:
Step2Activity=>Step1Acitivity=>HomeActivity但是如果通过通知栏这样进入Step2Activity 点回退 会直接退回到Android 桌面。就是因为 PendingIntent会默认开启新的任务栈1
解决方法:通过TaskStackBuilder设置具体的回退路径,在 AndroidManifest.xml定义Acitivity从属关系。
- 为Activity设置新的任务栈
Android 4.0.3 及更早版本
Android 4.1 及更高版本
1
2
3
4
5
6
7
8
9在代码中做如下处理:
```java
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从属关系。
1 | <activity |
在代码中申明:
1 | Intent intent = new Intent(this, ChildActivity.class); |
通过启动一个无任何层级关系的Acitity 激活应用(目前Lianlian3.0应用采用此方法)1
2
3
4
5
6
7
8
9public class SimpleLaunchAppActivity extends Activity {
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的解决方案:1
2过启动一个无任何层级关系的TransparentSwitchActivity 激活应用**
目前存在的问题是TransparentSwitchActivity里面会根据参数判断 通过通知进入后还有部分逻辑不太人性化和完善。需要提高用户体验。
- 关于系统默认的清空返回栈
如何用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。当然,既然说是默认的行为,那就说明我们肯定是有办法来改变的,在Manifest中 元素中设置以下几种属性就可以改变系统这一默认行为:1
2
3
4
5
6alwaysRetainTaskState
如果将最底层的那个Activity的这个属性设置为true,那么上面所描述的默认行为就将不会发生,任务中所有的Activity即使过了很长一段时间之后仍然会被继续保留。
clearTaskOnLaunch
如果将最底层的那个Activity的这个属性设置为true,那么只要用户离开了当前任务,再次返回的时候就会将最底层Activity之上的所有其它Activity全部清除掉。简单来讲,就是一种和alwaysRetainTaskState完全相反的工作模式,它保证每次返回任务的时候都会是一种初始化状态,即使用户仅仅离开了很短的一段时间。
finishOnTaskLaunch
这个属性和clearTaskOnLaunch是比较类似的,不过它不是作用于整个任务上的,而是作用于单个Activity上。如果某个Activity将这个属性设置成true,那么用户一旦离开了当前任务,再次返回时这个Activity就会被清除掉。
参考:
[1]. Activity启动模式 https://blog.csdn.net/lixiaodaoaaa/article/details/51700981