摘要
目前:新闻里的正文页Activity为NewspageActivity,其余专题、视频、图集等页面都使用SingleFragmentActivity。
在做消息推送通过Notification点击跳转时,代码如下:
|
|
必须使用Intent.FLAG_ACTIVITY_NEW_TASK的原因是:在app不存在任何栈的时候,需要新建一个栈。
现象一
但是官方说明里关于Intent.FLAG_ACTIVITY_NEW_TASK的描述有这么一段话:
初步理解是当使用Intent.FLAG_ACTIVITY_NEW_TASK,如果栈里已经存在要启动的Activity,那么Activity不会被创建。
测试验证确实是,当两条Notification都是跳转至NewspageActivity,在Launcher页面点击第一条Notification可正确跳转,但点击第二条Notification则没有反应。
现象二
基于现象一,再次仔细测试,发现并不是栈里存在要启动的AActivity,AActivity不会创建。看以下测试结果:
发现是通过AActivity创建的栈,再次点击Notification跳转至AActivity无效果,而在栈内的其他BActivity、CActivity是可以再次跳转打开的。
自以为的解决方案一
基于以上分析,如果想解决问题,我们只要封装一个统一的PushActivity分发数据,随后finish掉自己。
模拟代码
写了个demo测试,demo中包含3个Activity,MainActivity,OneActivity,TwoActivity.
MainActivity:主要作用是创建Notification。Notification的点击跳转统一跳转至OneActivity。
OneActivity:onCreate()中通过以下代码
|
|
跳转至TwoActivity,并finish()自己。
TwoActivity:打印生命周期的调用。并获取intent的flags。代码如下:
|
|
AndroidManifest.xml:都是默认设置。
|
|
结局
通过OneActivity做中转,每次点击Notification统一跳转至OneActivity,再由OneActivity去分发数据跳转至对应页面,分发数据完成后调用OneActivity.finish()方法。
这样每次点击Notification,栈里都不会存在OneActivity,那么应该都可以跳转了。但事实并非如此。
当收到两条Notification,在Launcher页面点击第一条Notification可正确跳转至OneActivity,但点击第二条Notification则没有反应。
无意尝试的解决方案二
解决方案一失败后,查看Intent的Flag其实并没有什么好招。
于是目光转向OneActivity的launchmode属性。
在不指定activity的launchmode属性,默认为standard。
突发奇想把它改成singleTask,发现问题完美解决。
|
|
点击第一条Notification生命周期大致为:
OneActivity#onCreate() taskid:2581;com.example.xiongcen.myapplication.OneActivity@ec892a6
->OneActivity#getFlag() flags:268435456
->TwoActivity#onCreate() taskid:2581;com.example.xiongcen.myapplication.TwoActivity@dca4873
->TwoActivity#getFlag() flags:0
->OneActivity#onDestroy()
点击第二条Notification生命周期大致为:
TwoActivity#onPause() com.example.xiongcen.myapplication.TwoActivity@dca4873
->OneActivity#onCreate() taskid:2581;com.example.xiongcen.myapplication.OneActivity@ca3d2b6
->OneActivity.getFlag flags:268435456
->TwoActivity#onCreate() taskid:2581;com.example.xiongcen.myapplication.TwoActivity@39061f2
->TwoActivity#getFlag() flags:0
->OneActivity#onDestroy()
->TwoActivity#onStop() com.example.xiongcen.myapplication.TwoActivity@dca4873
在OneActivity#onCreate()中通过getFlags()方法获取intent的flag,十进制为268435456,转成十六进制为0x10000000,即为Intent#FLAG_ACTIVITY_NEW_TASK。
在TwoActivity#onCreate()中通过getFlags()方法获取intent的flag,十进制数为0,这是因为我们在OneActivity启动TwoActivity时并没有添加任何flag。
尝试其他方案
经过方案二,尝试将OneActivity的launchmode改成singleInstance。
|
|
singleInstance比较典型的就是,启动launchmode为singleInstance的activity,栈id和其他默认栈id是不同的,是一个单独的栈,并且这个栈内只有该activity。
但设置android:taskAffinity属性后,android:taskAffinity指定名字的栈存在的话,OneActivity就不会新建,而是走onNewIntent()->onRestart()->onStart()->onResume()。
尝试结果发现,点击第一条Notification:
OneActivity#onCreate() taskid:2704;com.example.xiongcen.myapplication.OneActivity@ec892a6
->OneActivity#getFlag() flags:268435456
->TwoActivity#onCreate() taskid:2705;com.example.xiongcen.myapplication.TwoActivity@dca4873
->TwoActivity#getFlag() flags:268435456
->OneActivity#onDestroy()
点击第二条Notification:
TwoActivity#onPause() com.example.xiongcen.myapplication.TwoActivity@dca4873
->OneActivity#onCreate() taskid:2706;com.example.xiongcen.myapplication.OneActivity@ca3d2b6
->OneActivity#getFlag() flags:268435456
->TwoActivity#onResume() 2705;com.example.xiongcen.myapplication.TwoActivity@dca4873
->TwoActivity#getFlag() flags:268435456
->OneActivity#onDestroy()
在OneActivity#onCreate()中通过getFlags()方法获取intent的flag,十进制为268435456,转成十六进制为0x10000000,即为Intent#FLAG_ACTIVITY_NEW_TASK。
在TwoActivity#onCreate()中通过getFlags()方法获取intent的flag,十进制为268435456,转成十六进制为0x10000000,即为Intent#FLAG_ACTIVITY_NEW_TASK。
通过生命周期的打印可以看出TwoActivity并没有创建多个。
分析原因是:
猜测和打开TwoActivity的flags有关。
可以看到,在launchmode为singleTask的情况下,TwoActivity的flags=0,应该打开方式默认是standard,所以每次TwoActivity都会创建新的;在launchmode为singleInstance的情况下,TwoActivity的flags=268435456,转成十六进制为0x10000000,Intent#FLAG_ACTIVITY_NEW_TASK,根据文档说明知道设置FLAG_ACTIVITY_NEW_TASK,只要后续入栈的Activity和因为设置NEW_TASK标识而新起的栈建立的第一个Activity一致,就会导致相同Activity无法入栈,所以再次打开TwoActivity会无反应。
IntentFlag和Launchmode的关系
应该是IntentFlag设置的优先生效,但在不冲突的情况下也有可能和Launchmode搭配使用,例如测试Demo中OneActivity设置launchmode为singleTask,启动OneActivity设置IntentFlag为FLAG_ACTIVITY_NEW_TASK。