0
点赞
收藏
分享

微信扫一扫

Android activity启动流程分析

Java旺 2021-09-22 阅读 54
日记本

      前端时间看了一下framework的源码,把activity启动流程系统的学习了一下,涉及的源代码较多,本文是基于Android 8.1.0,从Launcher点击启动一个应用作为例子,我们分阶段来详细分析一下Activity启动流程:

一.Launcher到AMS阶段

      当在Launcher上点击应用图标后,会通过startActivity()来启动该应用的主activity,Launcher本身也是一个activity,调用startActivity()后,会调用到ContextThemeWrapper.startActivity()--->ContextWrapper.startActivity()--->
ContextImpl.startActivity(),看一下ContextImpl.java里面的逻辑:

a.ContextImpl.java
public void startActivity(Intent intent, Bundle options) {
    .......
    mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity) null, intent, -1, options);
}

      在startActivity()内部会调用Instrumentation的execStartActivity()方法,可以看到:Instrumentation对象是通过mMainThread.getInstrumentation()来获取的,此处的mMainThread是指ActivityThread实例,即Launcher进程的主线程,是在进程创建时就启动了,ActivityThread启动后在创建Launcher activity时会创建Instrumentation对象。接着分析Instrumentation的execStartActivity()方法:

b.Instrumentation.java
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ......
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
    }

      可以看到:在Instrumentation的execStartActivity()内部会调用到AMS的startActivity()方法,接下来就会进入下一阶段。

c.阶段调用流程图

二.AMS到preApp pause完成阶段

a.调用流程

      通过ActivityManagerService.startActivity(),会调用到ActivityStarter.startActivity(),然后经过一系列调用处理,会调用到ActivityStackSupervisor里面,然后再调用到ActivityStack里面。具体代码就不贴了,想了解的可以直接看源码。
      我们知道,在新的activity启动前,必须先将前一个activity pause,本实例中即在Launcher pause完成后才能启动新的应用activity,在ActivityStack里面调用前一个应用ActivityThread里面的ApplicationThread的schedulePauseActivity()来进行pause,pause完成后通知ActivityManagerService,再由ActivityManagerService通知ActivityStack来启动新的应用activity。

b.阶段调用流程图


      注意一下:在前一个app的activity通知执行完completePausedLocked()中,会执行finishCurrentActivityLocked()方法,在该方法中会执行addToStopping将preApp的ActivityRecord加入到ActivityStackSupervisor的mStoppingActivities变量里面,然后执行scheduleIdleLocked(),发送IDLE_NOW_MSG[该msg不会立即执行,会在空闲时执行,确保先执行current app的onCreate()、onStart()、onResume()],执行activityIdleInternal(),然后执行activityIdleInternalLocked(),最后调用到ActivityStack的stopActivityLocked(),调用到AppThread的scheduleStopActivity(),调用ActivityStack的destroyActivityLocked(),调用到AppThread的scheduleDestroyActivity(),然后跟AMS交互。

三.ASS到新应用ApplicationThread阶段

      在阶段二中,当前一个activity pause完成通知ActivityStack后,ActivityStack会调用ActivityStackSupervisor里面,一系列调用后,会调用到startSpecificActivityLocked(),一起看一下该方法:

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        // 判断该activity对应的进程是否已经启动
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.getStack().setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                //如果进程已经启动了,直接跟ApplicationThread进程通信启动该activity
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
        //进程没有启动,需要现将进程启动
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
}

      从上面可以看到,在启动前先判断app进程是否启动,如果启动了,直接调用realStartActivityLocked()来启动activity;否则,需要先启动进程。
      a.直接启动activity

//ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    ......
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);
    ......
    ......
}

      在realStartActivityLocked()里面调用到ApplicationThread的scheduleLaunchActivity()。
      app是ProcessRecord对象,包含了该应用进程的所有信息,thread是指该进程中ActivityThread中的ApplicationThread对象,该变量是在ActivityThread的main()--->ActivityManagerService.attachAppliaction()--->
ActivityManagerService.attachAppliactionLocked()中的app.makeActive()中将ApplicationThread赋值给ProcessRecord。
      b.先启动进程后启动activity

//ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ......
    ......
    //创建ProcessRecord对象
    app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
    ......
    //启动Process
    startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ......
    ......
    startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);
    ......
    ......
}

      如果process没有启动,则需要先new process,然后start process,调用到Process.start(),最终调用到ZygoteProcess.zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote),通过socket与Zygote进程通信,然后Zygote创建process。
      process创建完成后,会调用到ActivityThread.main()方法,随后调用流程如下:
      --->attach()
            --->ActivityManagerService.attachAppliaction()
                  --->ActivityManagerService.attachAppliactionLocked()
                        --->ActivityStackSupervisor.attachAppliactionLocked()
                              --->ActivityStackSupervisor.realStartActivityLocked()
                                    --->ApplicationThread.scheduleLaunchActivity()。


      在ActivityManagerService.attachAppliactionLocked()里面会先调用ApplicationThread的bindApplication()方法,继而调用ActivityThread的handleBindApplication()方法,该方法里面主要执行了以下逻辑:
      a:通过getPackageInfo()创建LoadedApk[用于广播接收回调,进程间通信ServiceConnection回调,创建application等];
      b:通过ContextImpl.createAppContext创建ContextImpl;
      c:通过反射创建Instrumentation实例mInstrumentation;
      d:通过LoadedApk的makeApplication创建Application,然后执行mInstrumentation.callApplicationOnCreate(app),调用了Application的onCreate()方法。

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
            .......
            .......
        try {
            java.lang.ClassLoader cl = getClassLoader();
            .......
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } ......
        .......
        return app;
    }

      最终还是通过Instrumentation来进行创建application,先创建application,然后调用application的attach()方法,传入context,最后返回application:

static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

四.ApplicationThread到Activity onCreate()阶段

      调用scheduleLaunchActivity后,通过sendMessage()会调用ActivityThread的handleLaunchActivity():

//ActivityThread.java
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ......
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        }
        .....
    }

      以上可以看到,在方法内会调用performLaunchActivity()方法:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ......
        }
        ......
       activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
        ......
        if (r.isPersistable()) {
           mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
           mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        ........
    }

      通过Instrumentation来new activity,然后调用activity.attach()方法(后面会有介绍),接下来调用Instrumentation.callActivityOnCreate(),调用activity.performCreate(),最终会调用activity.onCreate(),至此activity创建完成。



      简单介绍一下在执行activity.onCreate()之前会先调用activity.attach(),在其内部会执行以下逻辑:

final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window, 
            ActivityConfigCallback activityConfigCallback) {
        
        attachBaseContext(context);
        ......
        //创建PhoneWindow,后续在setContentView时会用到
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        .......
        .......
        //赋值
        .......
        //给PhoneWindow设置setWindowManager
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        ......
        //再将值给activity,后续在ActivityThread的handleResumeActivity()显示界面会用到
        mWindowManager = mWindow.getWindowManager();
}

五.相关类介绍

ActivityManagerService
      Android系统中一个特别重要的系统服务,也是我们上层APP打交道最多的系统服务之一。主要负责四大组件的启动、切换、调度以及应用进程的管理和调度工作。
ActivityStackSupervisor
      负责所有ActivityStack的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
ActivityStack
      Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
ActivityThread
      ActivityThread 运行在UI线程(主线程),App的真正入口。
ApplicationThread
      用来实现AMS和ActivityThread之间的交互。
Instrumentation
      负责调用Activity和Application生命周期。
ActivityRecord
      历史栈中的一个条目,代表一个activity。ActivityRecord中的成员变量task表示其所在的TaskRecord,ActivityRecord与TaskRecord建立了联系。
TaskRecord
      内部维护一个 ArrayList<ActivityRecord> 用来保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord与ActivityStack建立了联系。
ActivityStack
      内部维护了一个 ArrayList<TaskRecord> ,用来管理TaskRecord,ActivityStack中持有ActivityStackSupervisor对象,由ActivityStackSupervisor创建。
ProcessRecord
      包含一个进程的所有信息。

六.AMS启动过程

      AMS是在SystemServer中被添加的,所以先到SystemServer中查看初始化,参照SystemServer.java

/**
  * The main entry point from zygote.
  */
public static void main(String[] args) {
    new SystemServer().run();
}

      在run()方法中,创建SystemServiceManager对象,然后启动一些service。

private void run() {
    ......
    ......
    // Prepare the main looper thread (this thread).
    android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
    android.os.Process.setCanSelfBackground(false);
    Looper.prepareMainLooper();

    // Initialize native services.
    System.loadLibrary("android_servers");

    // Initialize the system context.
    createSystemContext();

    // Create the system service manager.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    .......
    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    }

   // Loop forever.
   Looper.loop();
}

      ActivityManagerService是在startBootstrapServices()中创建启动的。

private void startBootstrapServices() {
    ......
    ......
    // Activity manager runs the show.
    traceBeginAndSlog("StartActivityManager");
    mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    traceEnd();
    ......
    ......
    // Set up the Application instance for the system process and get started.
    traceBeginAndSlog("SetSystemProcess");
    //将自己注册到ServiceManager中,供IPC调用
    mActivityManagerService.setSystemProcess();
    traceEnd();
    .......
}

      AMS是通过SystemServiceManager.startService去启动的,参数是ActivityManagerService.Lifecycle.class, 首先看看SystemServiceManager.java的startService方法调用逻辑:

    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            ......
        }
        return startService(serviceClass);
    }

      通过传入的类名字获取到对应的class,接着将该class作为参数传入执行下一个startService()方法:

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            ......
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } 
            ......

            startService(service);
            return service;
        }
        ......
    }

      通过反射获取到类的构造方法,然后通过newInstance()来创建实例,接着将该实例作为参数传入执行下一个startService()方法:

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } 
        ......
    }

      startService方法很简单,是通过传进来的class然后反射创建对应的service服务。所以此处创建的是Lifecycle的实例,然后在startService中执行了service.onStart()。
      上面创建ActivityManagerService时传入的是ActivityManagerService.Lifecycle.class,看一下这个类:

    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }

      通过以上类可以看到,LifeCycle继承SystemService[SystemService是一个抽象类],在构造方法中创建了ActivityManagerService对象mService,然后通过getService()可以获取到mService。
      看一下ActivityManagerService初始化主要做了什么:

public ActivityManagerService(Context systemContext) {
    ......
    //管理bindService()相关逻辑
    mServices = new ActiveServices(this);
    ......
    //创建ActivityStackSupervisor对象,核心类,管理activity stack
    mStackSupervisor = createStackSupervisor();
    //监听task变化
    mTaskChangeNotificationController =
                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
   //管理startActivity()相关逻辑
    mActivityStarter = new ActivityStarter(this, mStackSupervisor);
   //最近使用任务
    mRecentTasks = new RecentTasks(this, mStackSupervisor);
    //启动一个线程专门跟进cpu当前状态信息,AMS对当前cpu状态了如指掌,可以更加高效的安排其他工作
    mProcessCpuThread = new Thread("CpuTracker") {
            @Override
            public void run() {
                synchronized (mProcessCpuTracker) {
                    mProcessCpuInitLatch.countDown();
                    mProcessCpuTracker.init();
                }
                while (true) {
                    try {
                        try {
                            synchronized(this) {
                                final long now = SystemClock.uptimeMillis();
                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
                                //        + ", write delay=" + nextWriteDelay);
                                if (nextWriteDelay < nextCpuDelay) {
                                    nextCpuDelay = nextWriteDelay;
                                }
                                if (nextCpuDelay > 0) {
                                    mProcessCpuMutexFree.set(true);
                                    this.wait(nextCpuDelay);
                                }
                            }
                        } catch (InterruptedException e) {
                        }
                        updateCpuStatsNow();
                    } catch (Exception e) {
                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
                    }
                }
            }
        };
     //看门狗,监听进程。这个类每分钟调用一次监视器,如果进程没有任何返回就杀掉
     Watchdog.getInstance().addMonitor(this);
     Watchdog.getInstance().addThread(mHandler);
}

      在构造方法中做了许多初始化工作,包括启动service相关的ActiveServices,启动activity相关的ActivityStarter,管理activity stack相关的ActivityStackSupervisor,最近任务相关的RecentTasks等,前面可以看到,在SystemServer中会先启动ActivityManagerService,启动完成后会执行setSystemProcess(),看一下setSystemProcess()做了什么工作:

public class ActivityManagerService extends IActivityManager.Stub implements xxx {
    .......
    .......
    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        }
            ......
            .......
    }
    .......
    .......
}

      注册服务。首先将ActivityManagerService注册到ServiceManager中,其次将几个与系统性能调试相关的服务注册到ServiceManager。此时其他进程可以通过ServiceManager.getService(Context.ACTIVITY_SERVICE)获取到IBinder,IActivityManager.Stub.asInterface(IBinder)可以获取到ActivityManagerService,然后可以与ActivityManagerService进行IPC了。
      前面讲到在SystemServer的main()中会执行一系列启动services,如下:

// Start services.
try {
    traceBeginAndSlog("StartServices");
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    SystemServerInitThreadPool.shutdown();
}

      在startBootstrapServices()中会启动ActivityManagerService,然后在startOtherServices()中会执行到以下逻辑:

    mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        ......
        ......

        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
            traceBeginAndSlog("StartCarServiceHelperService");
            mSystemServiceManager.startService(CarServiceHelperService.class);
            traceEnd();
        }

        traceBeginAndSlog("StartSystemUI");
        try {
            startSystemUi(context, windowManagerF);
        }
        .......
        .......
    }, BOOT_TIMINGS_TRACE_LOG);

    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

      通过以上可以看到,会执行到ActivityManagerService的systemReady()方法,然后启动CarServiceHelperService,接下来会启动SystemUISerivce,找到了启动SystemUISerivce的地方,接下来分析一下ActivityManagerService的systemReady()内部主要做了什么工作:

    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
        traceLog.traceBegin("PhaseActivityManagerReady");
        synchronized(this) {
            if (mSystemReady) {
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }

            .......
            mSystemReady = true;
        }
        .......
        .......
        if (goingCallback != null) goingCallback.run();
        .......
        synchronized (this) {
            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);

            .......
            startHomeActivityLocked(currentUserId, "systemReady");
            .......
        }
    }

      通过以上可以看到,在systemReady()中,有两处比较重要的地方是:
      1.执行startPersistentApps(),启动那些在AndroidManifest.xml中设置了android:persist="true"的app。
      2.执行startHomeActivityLocked(),启动home activity,比如手机端应该是启动了Launcher。

七.Activity启动模式

      activity有四种启动模式,分别为standard,singleTop,singleTask,singleInstance。如果要使用这四种启动模式,必须在manifest文件中<activity>标签中的launchMode属性中配置。
singleTask:
      启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制,即taskAffinity属性。
      taskAffinity:默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的应用中的activity的taskAffinity设置成相同的值,当两个不同应用中的activity设置成相同的taskAffinity时,则两个activity会属于同一个TaskRecord。
      在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity;如果这个已存在的任务中不存在一个要启动的Activity的实例,则在这个任务的顶端启动一个实例;若这个任务不存在,则会启动一个新的任务,在这个新的任务中启动这个singleTask模式的Activity的一个实例。
singleInstance:
      以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
      以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中(官方文档上的描述为,singleInstance模式的Activity不允许其他Activity和它共存在一个任务中)。
      被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启,受条件的限制,这个条件是:当前系统中是不是已经有了一个activity B的taskAffinity属性指定的任务。

举报

相关推荐

0 条评论