前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Intent.FLAG_ACTIVITY_CLEAR_TOP与SingleTask的区别

Intent.FLAG_ACTIVITY_CLEAR_TOP与SingleTask的区别

作者头像
None_Ling
发布2019-08-08 09:54:03
1.4K0
发布2019-08-08 09:54:03
举报
文章被收录于专栏:Android相关

起因

在测试Activity的启动过程中,测试Intent.FLAG_ACTIVITY_CLEAR_TOP以及SingleTask的过程中发现这两者有一些区别。

实验条件

准备了4个Activity,分别为:MainActivitySecondActivityThirdActivityFourthActivity

启动顺序为:MainActivity --> SecondActivity --> ThirdActivity --> FourthActivity --> SecondActivity

实验过程

FourthActivity启动SecondActivity中测试Intent的Flag以及LaunchMode的影响结果。

第一种:在Intent中加入Intent.FLAG_ACTIVITY_CLEAR_TOP

测试结果

在加入了Intent.FLAG_ACTIVITY_CLEAR_TOP的标识位之后:

  • 仍然会先清理指定Activity(即SecondActivity)之上的Activity
  • 但是原来存在的Activity会先被清理掉,接着会创建一个新的Activity对象来替代
测试日志
代码语言:javascript
复制
E/MainActivity: MainActivity onResume...  
E/MainActivity: MainActivity onPause...
  //  SecondActivity启动
E/SecondActivity: SecondActivity onResume...com.timmy.sotest.SecondActivity@e4c8987 
E/SecondActivity: SecondActivity onPause...
E/ThirdActivity: ThirdActivity onResume...
E/SecondActivity: SecondActivity onStop...
E/ThirdActivity: ThirdActivity onPause...
E/FourthActivity: FourthActivity onResume...
//  开始启动SecondActivity,先把ThirdActivity销毁
E/ThirdActivity: ThirdActivity onStop...
E/ThirdActivity: ThirdActivity onDestroy...
//  再开始启动SecondActivity流程
E/FourthActivity: FourthActivity onPause...
//  销毁之前存在的SecondActivity
E/SecondActivity: SecondActivity onDestroy...com.timmy.sotest.SecondActivity@e4c8987
//  重新创建新的SecondActivity
E/SecondActivity: SecondActivity onResume...com.timmy.sotest.SecondActivity@9b9f44
//  最后销毁FourthActivity
E/FourthActivity: FourthActivity onStop...
E/FourthActivity: FourthActivity onDestroy...

第二种:LaunchMode设置为SingleTask

测试结果

在Manifest.xml中设置LaunchMode后:

  • 同样会清理指定Activity(即SecondActivity)之上的Activity
  • 而会使用原来的Activity,并不会销毁原来的Activity之后重新创建
测试日志
代码语言:javascript
复制
E/MainActivity: MainActivity onResume...
E/MainActivity: MainActivity onPause...
//  SecondActivity启动
E/SecondActivity: SecondActivity onResume...com.timmy.sotest.SecondActivity@e4c8987
E/SecondActivity: SecondActivity onPause...
E/ThirdActivity: ThirdActivity onResume...
E/SecondActivity: SecondActivity onStop...
E/ThirdActivity: ThirdActivity onPause...
//  FourthActivity启动
E/FourthActivity: FourthActivity onResume...
E/ThirdActivity: ThirdActivity onStop...
E/ThirdActivity: ThirdActivity onDestroy...
//  开始启动SecondActivity
E/FourthActivity: FourthActivity onPause...
E/SecondActivity: SecondActivity onRestart...
//  使用原来的SecondActivity
E/SecondActivity: SecondActivity onResume...com.timmy.sotest.SecondActivity@e4c8987
E/FourthActivity: FourthActivity onStop...
E/FourthActivity: FourthActivity onDestroy...

原因

ActivityStarter.startActivityUnchecked函数中,在找到要启动的Activity所保存的TaskRecord后,会来处理该标识位:

代码语言:javascript
复制
            //  如果设置了FLAG_ACTIVITY_CLEAR_TOP,或者mLaunchSingleInstance,mLaunchSingleTask则会进入该逻辑
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || mLaunchSingleInstance || mLaunchSingleTask) {
                //  首先获取复用的Activity所在的Task
                final TaskRecord task = reusedActivity.getTask();
                //  接着调用performClearTaskForReuseLocked来清理Task中的Activity
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);
                ...
                if (top != null) {
                   ...
                    //  如果返回来ActivityRecord不为空,则回调onNewIntent函数
                    top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
                            mStartActivity.launchedFromPackage);
                }
            }

TaskRecord.performClearTaskForReuseLocked函数中,会开始清理复用的Activity上方的Activity。

代码语言:javascript
复制
final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
        int numActivities = mActivities.size();
        //  开始遍历Task中所有的Activity,从顶往下遍历
        for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
            ActivityRecord r = mActivities.get(activityNdx);
            if (r.finishing) {
                continue;
            }
            //  如果找到要启动的Activity的话
            if (r.realActivity.equals(newR.realActivity)) {
                // Here it is!  Now finish everything in front...
                final ActivityRecord ret = r;

                for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
                    //  开始遍历要启动的Activity之上的Activity
                    r = mActivities.get(activityNdx);
                    if (r.finishing) {
                        continue;
                    }
                    //  调用finishActivityLocked开始清理Activity
                    if (mStack != null && mStack.finishActivityLocked(
                            r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
                        --activityNdx;
                        --numActivities;
                    }
                }

                // Finally, if this is a normal launch mode (that is, not
                // expecting onNewIntent()), then we will finish the current
                // instance of the activity so a new fresh one can be started.
                //  接着判断当前Activity的LaunchMode如果是LAUNCH_MULTIPLE,也就是默认的LaunchMode,
                //  并且没有FLAG_ACTIVITY_SINGLE_TOP的话,就开始调用finishActivityLocked来结束该Activity
                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
                        && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
                        && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
                    if (!ret.finishing) {
                        if (mStack != null) {
                            mStack.finishActivityLocked(
                                    ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
                        }
                        return null;
                    }
                }
                return ret;
            }
        }
        return null;
    }

所以,到此就知道了如果LaunchMode为默认的话,并且没有设置FLAG_ACTIVITY_SINGLE_TOP则会把原来的Activity销毁,重新创建新的Activity。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.08.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 起因
  • 实验条件
  • 实验过程
    • 第一种:在Intent中加入Intent.FLAG_ACTIVITY_CLEAR_TOP
      • 测试结果
      • 测试日志
    • 第二种:LaunchMode设置为SingleTask
      • 测试结果
      • 测试日志
  • 原因
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档