Android 启动模式(launchMode)

来源:互联网 发布:qq刷人气软件 编辑:程序博客网 时间:2024/06/13 02:18

通过  adb shell dumpsys activity ,对于4种launchMode进行分析

standerd:

标准启动模式,在每次启动Activity时都会创建一个新的Activity。

归属栈:Activity会被压入启动它的activity所在栈。


singleTop:

如果Activity在栈顶,则不会重新创建Activity,同时调用Activity的onNewIntent方法。如果要启动的Activity不在栈顶,则会创建新的Activity。

 归属栈:如果是创建新的Activity,和standerd一样,Activity会被压入启动它的activity所在栈,这里与FLAG_ACTIVITY_SINGLE_TOP该flag类似。


singleTask:

如果要启动的Activity已经存在,则不会创建该Activity,并将该栈位于Activity之上的所有其他Activity出栈,同时调用Activity的onNewIntent方法。如果该Activity不存在,则会创建新的Activity。

归属栈:singleTask相对与以上两种模式特殊,如果创建新的Activity,singleTask的归属栈决定于它的taskAffinity属性,如果没有配置,默认是包名,从dumpsys activity可以看到,TaskRecord{42ee9a08 #26 A com.test.launchermodetest U 0},其中com.test.launchermodetest则为taskAffinity的值,用于标识这个TaskRecord,所以启动新创建的Activity,则会判断是否已经存在标识该taskAffinity的栈,存在则压入栈中,不存在则直接创建新的任务栈,再将activity入栈。这里FLAG_ACTIVITY_NEW_TASK 也可以这么理解,在以这个flag启动一个activty时,便是通过taskAffinity判断是否创建新的TaskRecord。 因此一个app如果由launcher启动,默认会以FLAG_ACTIVITY_NEW_TASK方式启动,这时会创建一个taskAffinity为该包名的任务栈,这时当app再启动一个activity,即使为singleTask模式,也不会创建新的任务栈,除非指定其他的taskAffinity值。


singleInstance:可以理解为全局单例,如果activity不存在,创建一个新栈,栈中只会存在唯一一个Activity实例。


记录,之前测试的一个问题,直接拉一个TaskRecord到最前,类似长按home键选择历史app栈,发现

        Intent intent = context.getPackageManager().getLaunchIntentForPackage(pkgName);
        intent.setAction(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        context.startActivity(intent);

这种方式有个问题,总是启动的是该栈的MainActivity,而不是按原先的activity顺序将整个栈移到最前面,最后发现intent.setPackage(null),将intent的PackageName设置为null后正常,这个问题比较困惑,初步跟踪AMS,确实有判断intent 的Package 属性是否设置,并进行相应处理,但细节还未跟踪,这里记录下次分析跟踪。


原创粉丝点击