写在开头
根据对Android启动activity的launchMode方式进行了解后,在将其设置为singleTop或者singleTask后,便可以防止在界面中重复点击之后启动多个activity的情况。然而,在公司项目中使用了该方式后发现了一个问题,当启动一个activity使用的方法为startActivityForResult时,使用singleTop或者singleTask并无法防止重复点击,仍旧会触发两个activity。
问题来源
在5.0之前的源码中,先将启动模式进行判断,判断为不是FLAG_ACTIVITY_NEW_TASK时, 会抛出“Activity is launching as a new task, so canceling activity result”, 之后并没有做任何处理,但是在5.0及5.0以后进行了处理,如图
5.0及5.0以后的源码为:
我们可以看到,虽然启动模式被设置为singleTask,后面会将启动模式重新设置为FLAG_ACTIVITY_NEW_TASK。
在startActivityForResult方法前有一段注释,写明了使用这个方法的相关协议。图中画框显示,假如一个activity的启动模式为FLAG_ACTIVITY_NEW_TASK,那么这个activity将不会在原先的task任务栈中被启动运行。
然而一个新的task任务栈中不会存放有其他的activity,也就不会有刚才activity A。新的task任务栈中没有匹配到activity A,会重新创建一个activity A并且压入栈了。
根据以上推断,我们可以得出以下结果:调用这个activity的启动方法为startActivityForResult,则相当于设置activity的启动模式为singleTask已经失效了,那么仍然会创建两个activity A。
解决方案:
1. 使用RxBinding,是Jake Wharton的开源库,将按钮的点击事件进行响应判断。
2. 在父类activity中对dispatchTouchEvent方法进行重写。当有一个触摸事件发生时,会直接到达根节点,即会调用子View的dispatchTouchEvent方法进行发送事件。获取当前事件,与上一次触摸事件进行比较,在一定时间范围内返回true,对该点击事件不做分发,按钮没有接受到点击事件,也就实现不再创建新的activity。
网友评论