主要总结下使用startActivity时需要注意的点
对于Activity的启动模式而言,我们可以通过设置不同的启动模式,来实现调配不同的Task。但是taskAffinity在一定程度上也会影响任务栈的调配流程。
每一个Activity都有一个Affinity属性,如果不在清单文件中指定,默认为当前应用的包名。taskAffinity主要有以下几点需要注意:
通过一个例子来验证一下,在一个Android项目TaskAffinity中,创建两个Activity:First和Second,除了Activity类名之外,其他都是默认配置。这种情况下,点击First中的Button,从First跳转到Second。通过命令 adb shell dumpsys activity activities
上述命令会将系统中所有存活中的Activity信息打印到控制台,这时我们可以看到在一个任务栈中存在两个Activity实例,并且Second处于栈顶。
接下来修改下Second的taskAffinity,将其改为“second.affinity”,使它和First的taskAffinity不同。这时再查看任务栈中的情况,可以看到虽然First和Second的taskAffinity不同,但是他们都被创建在一个任务栈中。
但是如果我们再将Second的launchMode改为singleTask,再次运行就会发现两个Activity会被分配到不同的任务栈中。
结论: 单纯使用taskAffinity不能导致Activity被创建在新的任务栈中,需要配合singleTask或singleInstance!!!
allowTaskReparenting赋予Activity在各个Task中间转移的特性 。一个在后台任务栈中的Activity A ,当有其他任务进入前台 ,并且taskAffinity与A相同 ,则会自动将A添加到当前启动的任务栈中 。
举例:
上面的现象原因就是allowTaskReparenting属性,通过代码演示下:
分别创建两个project过程:First和TaskAffinityReparent
先打开First app,并从FirstA开始跳转到B-C。然后按下Home键,使其进入后台。
接下来打开TaskAffinityReparent app,屏幕上本应显示ReparentActivity的页面,但实际却显示的时First C中的页面,通过命令可以看到,First C被移动到与ReparentActivity在同一个任务栈中。此时First C位于栈顶,再次点返回键,才会显示ReparentActivity页面
Activity界面跳转时,使用Intent传递数据是最常用的操作。但是Intent传值偶尔也会导致程序崩溃。如下代码:
在startFirstB方法中,跳转FirstB页面,并通过Intent传递Bean类中的数据。但是执行上述代码会报错:
log中的意思是Intent传递数据过大,最终原因是Android系统对使用Binder传数据进行了限制 。通常为1M,但根据不同版本,厂商,也会有变化。
解决方法 :
byte[] data
从而避免将其序列化。我们通常会在自定义的Application中做一些初始化的操作,比如app分包,推送初始化,库的全局配置等。但实际上, Activity可以在不同的进程中启动,而每一个不同的进程都会创建出一个Application ,因此有可能造成Application的onCreate()被多次执行。
比如在Manifest中为某个Activity配置process属性,这将导致它会在一个新的进程中创建。当从一个Activity在跳转到它时,Application会再被创建。
解决:
主要说了: