解析ActivityManagerService

解析 ActivityManagerService

       Android 系统启动过程、应用程序进程启动过程以及四大组件工作过程,都涉及了 ActivityManagerService(以后简称AMS) 本文将基于Android8.1.0系统来对AMS进行讲解。
 

    1. AMS 的启动过程

       要想更好地理解 AMS ,很有必要了解 AMS 的启动过程, AMS 的启动是在 SystemServer进程中启动的,关于 SystemServer 进程的启动过程在“Android系统启动流程(3) —— 解析SystemServer进程启动过程”中已经讲过,这里就从 SystemServer 的 main 方法开始分析,代码如下所示:

frameworks/base/services/java/com/android/server/SystemServer.java

    public static void main(String[] args) {
        new SystemServer().run();
    }

       在main方法中只调用了SystemService的run方法,代码如下所示:

frameworks/base/services/java/com/android/server/SystemServer.java

    private void run() {
        try {
            ...
            // 创建消息Looper
            Looper.prepareMainLooper();

            // 加载动态库libandroid_servers.so
            System.loadLibrary("android_servers"); // ... 1

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // 创建系统的Context
            createSystemContext();

            // 创建SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext); // ... 2
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            // 启动引导服务
            startBootstrapServices(); // ... 3
            // 启动核心服务
            startCoreServices(); // ... 4
            // 启动其他服务 
            startOtherServices(); // ... 5
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }
        if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
            final int MAX_UPTIME_MILLIS = 60 * 1000;
            if (uptimeMillis > MAX_UPTIME_MILLIS) {
                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                        "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
            }
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
       在注释1 处加载了动态库 libandroid _servers.so 。接下来在注释2 处创建 SystemServiceManager ,它会对系统的服务进行创建、启动和生命周期管理。在注释3处的 startBootstrapServices 方法中用 SystemServiceManager 启动了 ActivityManagerService、 PowerManagerService、 PackageManagerService 等服务 。在注释4 处的 startCoreServices 方法 中则启动了 DropBoxManagerService、BatteryService、 UsageStatsService 和  Web ViewUpdateService 。在注释5处的 startOtherServices 方法中启动了 CameraServiceProxy、AlarmManagerService、VrManagerService 等服务。  从注释3  、注释4 、注释5 处的方法可以看出,官方把系统服 务分为了3 种类型,分别是引导服务 、核 心服务和其他服务,其中其他服务是一 些非紧要和不需要立即启动的服务。我们主 要来查看引导服务 AMS 是如何启动的,注释3 处的 startBootstrapServices 方法代码 如下所示:
 
frameworks/base/services/java/com/android/server/SystemServer.java
 
    private void startBootstrapServices() {
        ...
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService(); // ... 1
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        traceEnd();
        ...
    }
       在注释1 处调用了 SystemServiceManager 的  startService 方法, 该方法的参数是 ActivityManagerService.Lifecycle.class,下面查看SystemServiceManager 的  startService 方法,代码如下所示:
 
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            // 获取Lifecycle类的名字
            final String name = serviceClass.getName(); 
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                // 获取Lifecycle的构造器
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                // 创建Lifecycle对象
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service); // ... 1
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
       在startService方法中,通过反射的方式创建了Lifecycle类的对象,在注释1处调用 SystemServiceManager的另一个startService方法,代码如下所示:
 
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service); // ... 1
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart(); // ... 2
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }
       传入的 SystemService 类型的 service 对象的值为 ActivityManagerServi c e.Lifecyc le .class。 在注释1处将 serv ice 对象 添加到 Array List 类型的 mServices 中来完成注册。在注释2 处调 service 的 on Start 方法 启动 s ervice 对象,这个 service 对象具体指的是什么呢?我们接 着往 下看, Lifecycle 是  AMS 的内部类,代码如下所示:
 
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 
    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

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

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

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

        public ActivityManagerService getService() { // ... 3
            return mService;
        }
    }
       上面的代码需要结合 SystemServiceManager 的  startService 方法 来分析。注释1 处,在 Lifecycle 的构造方法中创建了 AMS 实例 。当调 SystemService 类型的 service 的  on Start 方法时,实际上是调用了注释处 AMS 的  start 方法。 注释3 处的 Lifecycle 的 getService 方法 返回 AMS 实例,这样我们就知道 SystemServer 的  startBootstrapServices 方法的注释 1处mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService()实际 得到的就是 AMS 实例, AMS 的启动过程就讲到这里。
 
 

    2. AMS 与应用程序进程

       在“Android系统启动流程(2) —— 解析Zygote进程启动过程”一文中讲到了Zygote的java框架层中,会去创建一个Server端的Socket,这个Socket用来等待AMS请求Zygote来创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经存在。在启动应用程序时AMS会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程创建需要的应用程序进程。

       这里以Service的启动过程为例,来分析AMS与应用程序进程的关系。Service在启动过程中会调用ActiveService的bringUpServiceLocked方法,对Service启动流程不清楚的可以查看“解析Service的启动过程”这篇文章,代码如下所示:

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
 
        // 获取Service想要在哪个进程中运行
        final String procName = r.processName; // ... 1
 
        String hostingType = "service";
        ProcessRecord app;
 
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); // ... 2
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
 
            // 如果运行Service的应用程序进程存在
            if (app != null && app.thread != null) { // ... 3
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    // 启动Service
                    realStartServiceLocked(r, app, execInFg); // ... 4
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }
 
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } else {
            app = r.isolatedProc;
            if (WebViewZygote.isMultiprocessEnabled()
                    && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
                hostingType = "webview_service";
            }
        }
 
        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
 
        // 如果用来运行Service的应用程序进程不存在
        if (app == null && !permissionsReviewRequired) { // ... 5  
            // 创建应用程序进程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) { // ... 6
                String msg = "Unable to launch app "
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
        ... 
        return null;
    }
       在注释1 处得到 ServiceRecord 的  processName 的值并赋值给 procName ,其中 processName 用来描述 Service 想要在哪个进程运行,默认是当前进程,我们也可以在 AndroidManifest 文件中设置 android:process 属性来新开启一个进程运行 Serv ice 。在注释2 处将 procName 和  Service 的 uid 传入到 AMS 的  getProcessRecordLocked 方法 中,来查询是否存在一 个与 Service 对应的 ProcessRecord 类型的对象 app , ProcessRecord 主要用来描述运行的应用程序进程的信息。在注释5处判断 Service 对应的 app 为  null 则说明用来运行 Service 的应用程 序进程不存在,则调用注释6 处的 AMS 的  startProcessLocked 方法来创建对应的应用程序 进程,关于创建应用程序进程请 查看“ Android系统中应用程序进程的启动过程 的内容,在注释3 处判断如果用来运行 Service 的应用程序进程存在,则 调用 注释4 处的 realStartServiceLocked 方法 来启动 Service AMS 与应用程序进程的关系主要有以下两点:
 
  • 启动应用程序时 AMS 会检查这个应用程序需要的应用程序进程是否存在。
  • 如果需要的应用程序进程不存在, AMS 会请 Zygote 进程创建需要的应用程序进程。

    3. AMS 重要的数据结构     

       AMS 涉及了很多数据结构,这 一节 我们来分析 Activity Record、TaskRecord、 ActivityStack ,为什么要学习它们呢?因为它们和应用开发关联较大,是 Activity 任务栈 模型的基础。
 

     3.1 解析 ActivityRecord

       ActivityRecord它内部记录了Activity的所有信息,因此它用来描述一个Activity,它在启动Activity时被创建,具体是在ActivityStarter的startActivity方法中被创建的,ActivityRecord 的部分重要成员变量 如表1所示。                                          

表1 ActivityRecord 的部分重要成员变量
                     名称                       类型                                                            说明
service ActivityManagerService AMS的引用
info AcitivityInfo Activity中代码和AndroidManifes设置的节点信息,比如launchMode
launchedFromPackage String 启动Activity的包名
taskAffinity String Activity希望归属的栈
task TaskRecord ActivityRecord所在的TaskRecord
app ProcessRecord ActivityRecord所在的应用程序进程
state ActivityState 当前Activity的状态
icon int Activity的图标资源标识符
theme int Activity的主题资源标识符
       从表1 可以看出 Activity Record 的作用,其内部存储了 Activity 的所有信息,包括 AMS 的引用、 AndroidManifes 节点信息、 Activity 状态、 Activity 资源 信息和  Activity 进程相关信息等,需要注意的是其中含有该 Activity Record 所在的 TaskRecord ,这就将 ActivityRecord 和TaskRecord 关 联在一 起,它们是 Activity任务栈 模型的重要 成员。

     3.2 解析 TaskRecord

       TaskRecord 用来描述一个 Activty 任务栈 内部也有很多 的成员变量  ,这里挑出一些重要的成员变量进行介绍,如表2所示:
表2 TaskRecord的部分重要成员变量
名称 类型 说明
taskId int 任务栈的唯一标识符
affinity String 任务栈的倾向性
intent Intent 启动这个任务栈的Intent
mActivities ArrayList<ActivityRecord> 按照历史顺序排列的Activity记录
mStack ActivityStack 当前归属的ActivityStack
mService ActivityManagerService AMS的引用
       从表2 可以发现 TaskRecord 的作用,其内部存储了任务栈的所有信息,包括任务栈的唯一标识符、任务栈的倾向性、任务栈中的 Activity 记录和 AMS 的引用等,需要注意的 是其中含有 ActivityStack ,也就是当前 Act ivity 任务栈 所归属的 Ac tivityStack 。

    3.3 解析 ActivityStack

       ActivityStack 是一 个管理类,用来管理系统所有 Activity ,其内部维护了 Activity 的所 有状态、特殊状态的 Ac tivity 以及和 Activity 相关的列表等数据。A ctivityStack 是由 ActivityStackSupervisor 来进行管理的,而 ActivityStackSupervisor 在 AMS 的构造方法中被 创建,代码如下所示:
 

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public ActivityManagerService(Context systemContext) {
        ...
        mStackSupervisor = createStackSupervisor();
        ...
    }

    protected ActivityStackSupervisor createStackSupervisor() {
        return new ActivityStackSupervisor(this, mHandler.getLooper());
    }

       1. ActivityStack的实例类型

        在ActivityStackSupervisor中有多种ActivityStack实例,代码如下所示:

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
    ...
    /** The stack containing the launcher app. Assumed to always be attached to
     * Display.DEFAULT_DISPLAY. */
    ActivityStack mHomeStack;

    /** The stack currently receiving input or launching the next activity. */
    ActivityStack mFocusedStack;

    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
     * been resumed. If stacks are changing position this will hold the old stack until the new
     * stack becomes resumed after which it will be set to mFocusedStack. */
    private ActivityStack mLastFocusedStack;
    ...
}
       mHomeStack 用来存储 Launcher App 的所有 Activity, mFocusedStack 表示 当前正在接 收输入 或启动下一个 Ac tiv ity 的所 有 Act ivity 。 mLastF ocusedStack 表示此前接收输入的所有 Activity 。通 ActivityStackSupervisor 提供了获取上述 ActivityStack 的方法,比如要获取 mFocusedStack ,只 需要 调用 Activi tyStackSupervisor的getF ocusedStack 方法 就可以了,代码如下所示:
 
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    ActivityStack getFocusedStack() {
        return mFocusedStack;
    }

       2. ActivityState

       在ActivityStack中通过枚举存储了Activity的所有状态,代码如下所示:

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
    enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }

       通过名称我们可以很轻易知道这些状态所代表的意义。ActivityState的场景会有很多,比如下面的代码:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    public void overridePendingTransition(IBinder token, String packageName,
            int enterAnim, int exitAnim) {
        synchronized(this) {
            ActivityRecord self = ActivityRecord.isInStackLocked(token);
            if (self == null) {
                return;
            }

            final long origId = Binder.clearCallingIdentity();

            if (self.state == ActivityState.RESUMED
                    || self.state == ActivityState.PAUSING) { // ... 1
                mWindowManager.overridePendingAppTransition(packageName,
                        enterAnim, exitAnim, null);
            }

            Binder.restoreCallingIdentity(origId);
        }
    }

       overridePendingTransition 方法用于设置 Activity 的切换动画, 在注释1处可以看到只有 ActivityState 为RESUMED 状态或 PAUSING 状态时才会调用 WMS 类型的 mWindowManager 对象的 overridePendingAppTransition 方法切换动画。

       3. 特殊状态的 Activity
 
       在Ac tivitySt ack 中定义了一些特殊状态的 Activity ,如下所示:

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

    /**
     * When we are in the process of pausing an activity, before starting the
     * next one, this variable holds the activity that is currently being paused.
     */
    ActivityRecord mPausingActivity = null; // 正在暂停的Activity

    /**
     * This is the last activity that we put into the paused state.  This is
     * used to determine if we need to do an activity transition while sleeping,
     * when we normally hold the top activity paused.
     */
    ActivityRecord mLastPausedActivity = null; // 上一个已经暂停的Activity

    /**
     * Activities that specify No History must be removed once the user navigates away from them.
     * If the device goes to sleep with such an activity in the paused state then we save it here
     * and finish it later if another activity replaces it on wakeup.
     */
    ActivityRecord mLastNoHistoryActivity = null; // 最近一次没有历史记录的Activity

    /**
     * Current activity that is resumed, or null if there is none.
     */
    ActivityRecord mResumedActivity = null; // 已经Resume的Activity

    // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
    // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
    // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
    // Activity in mTranslucentActivityWaiting is notified via
    // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
    // background activity being drawn then the same call will be made with a true value.
    ActivityRecord mTranslucentActivityWaiting = null; // 传递给convertToTranslucent方法的最上层的Activity
       这些特殊的状态都是 Activity Record 类型的, Activity Record 用来记录 Activity 的所有 信息。
       4. 维护的 Arraylist
   
       在ActivityStack中维护了很多ArrayList,这些ArrayList中的元素类型主要有ActivityRecord 和 TaskRecord,如表3所示:
表3 ArrayList 中的元素类型及其说明
ArrayList 元素类型 说明
mTaskHistory TaskRecord 所有没有被销毁的Activity任务栈
mLRUActivities ActivityRecord 正在运行的Activity,列表中的第一个条目是最近最少使用的Activity
mNoAnimActivities ActivityRecord 不考虑转换动画的Activity
mValidateAppTokens TaskGroup 用于与窗口管理器验证应用令牌
       ActivityStack 维护了元素类型为 TaskRecord 的列 表, 这样 ActivityStack 和  TaskRecord 有了关联, Activity 任务栈 存储在 ActivityStack 中。
 

     4. Activity栈管理

       做过应用开发的同学都知道Activity是放入在Activity任务栈中的,有了任务栈,系统和开发者就能够更好地应用和管理Activity来完成各种业务逻辑。

       1. Activity 任务栈模型

       Activity 任务栈 是由多种数据结构共同组合而成的,在第3 节已经分析了 Activity Record、TaskRecord、 ActivityStack ,它们就是 Activity 任务栈模型的 重要组成部分,如下图所示:
 

       ActivityRecord是 用来记录一个  Activity 的所有信息, TaskRecord 中包含了一个或多个 Activity Record , TaskRecord 用来表示 Activity 的任务栈,用来管理栈中的 Activity Record, ActivityStack 又包含了一 个或多个 TaskRecord ,它是 TaskRecord 的管理者。 Activity 栈 管理就是建立在 Ac tivity  任务栈模型之上的,有了栈管理,我们可以对应用程序进行操作,应用可以复用自身应用中以及其他应用的 Activity ,节省了资源。
 
       2. Launch Mode

       Launch Mode 用于设定Activity的启动方式,无论是哪种启动方式,所启动的Activity都会位于Activity栈的栈顶,主要有一下4中Launch Mode。

       1. standerd:默认模式,每次启动Activity都会创建一个新的Activity实例。

       2. singleTop:如果要启动的 Activity 已经在栈顶,则不会重新创建 Activity ,同时该 Activity 的 onNewlntent 方法会被调用。如果要启动的 Activity 不在栈顶,则会重新创建该 Activity 的实例。

       3. singleTask:如果要启动的 Activity 已经存在于它想要归属的栈中,那么不会创建该 Activity 实例,将栈中位于该 Activity 之上的所有的 Activity 移除栈,同时该 Activity 的 onNewlntent 方法会被调用。如果要启动的 Activity 不存在于它想要归属的栈中,并且该栈存在,则会重新创建该 Activity 的实例。如果要启动的 Activity 想要归属的校不存在,则首先要创建一个新栈,然后创建该 Activity 实例并压入到新栈中。

       4. singleInstance:和 singleTask 基本类似,不同的是启动 Activity 时,首先要创建一个新栈,然后创建该 Activity 实例并压入新栈中,新栈中只会存在这 一个 Activity 实例。

       3. Intent的FLAG

       在Intent 中定义了很多 FLAG ,其中有几个 FLAG 也可以设定 Activity 的启动方式,如果 Launch Mode 和 FLAG 设定的 Activity 的启动方式有冲突 ,则以 FLAG 设定的为准。

  •  FLAG_ACTIVITY_SINGLE_TOP :和 Launch Mode 中的 singleTop 效果是 样的。
  •  FLAG_ACTIVITY_NEW_TASK :和 Launch Mode 中的 singleTask 果是一样的。
  •  FLAG _ACTIVITY_CLEAR_TOP :在 Launch Mode 中没有与此对应的模式,如果要启动的 Activity 已经存在于栈中,则     将所有位于它上面的 Activity 出栈。 singleTask 默认具有此标记位的效果。

          除了上述这 FLAG ,还有一些 FLAG 对我们分析栈管理有些帮助。

  •  FLAG_ACTIVITY_NO_HISTORY :  Activity 一旦退出,就不会存在于栈中。同样地, 也可以 在AndroidManifest.xml中设   置 android:noHistory。
  •  FLAG_ACTIVITY_MULTIPLE_TASK :需要和 FLAG_ACTIVITY_NEW_TASK 一同使用才有效果,系统会启动一个新的栈来容纳新启动的 Activity。
  •  FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: Activity 不会被放入到“最近启动的 Activity ”列表中。
  •  FLAG_ACTIVITY_BROUGHT_TO_FRON :这个标志位通常不是由应用程序中的代码设置的,而是 Launch Mode 为singleTask 时,由系统自动加上的。
  •  FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY :这个标志位通常不是由应用程序中的代码设置的,而是从历史记录中启动的(长按 Home 键调出)。
  •  FLAG_ACTIVITY_CLEAR_ ASK :需要和 FLAG_ACTIVITY_NEW_TASK 一同使用才有效果,用于清除与启动的 Activity 相关栈的所有其他 Activity。

       4. taskAffinity

       我们可以在 AndroidManifest. xml 中设置  android:taskA ffinity ,用来指定 Activity 希望归属的栈 ,在默认情况下,同 一个应用程序的 所有的 Activity  都有 着相 同的 taskAffinity 。 taskAffinity 在下面两种情况时 会产生效果。
 
       ( 1 ) taskAffinity 与  FLAG_ ACTIVITY _NEW_ TASK 或者 single Task 配合。如果新启动 Activity 的 taskAffi nity 和栈的 taskAffi nity 相同则加入到该栈中;如果不同,就会创建新栈。
       (2) taskAffini ty 与  allowTaskReparenting 配合。如果 allowTaskReparenting 为  true ,说明  Activity 具有转移的能力

猜你喜欢

转载自blog.csdn.net/lixiong0713/article/details/107243282