美文网首页
Android ActivityManagerService--

Android ActivityManagerService--

作者: DarcyZhou | 来源:发表于2023-10-31 08:55 被阅读0次

本文转载自:深度详解 Android R(11.0)Activity 启动过程

本文基于Android 11.0源码分析

前言

  Activity启动过程是AMS系统中一个重要的代码流程,本篇文档将对该流程作详细的分析。根据Activity的启动时机,从如下两个方面入手:

  1. 根Activity的启动流程:又叫应用程序启动流程,即点击桌面上某一个应用图标到应用第一个Activity展示出来的流程;
  2. 普通Activity的启动流程:即应用内启动一个Activity到展示出来的流程。

  由于两种启动流程是有重叠的,根Activity的启动流程更复杂,所以下面我们基于 Android R(11.0) 重点分析根Activity的启动流程,而普通Activity的启动流程在涉及的地方会稍微提一下。

  应用的启动流程大致分为下面五个阶段:

(1)应用启动进程Launcher调用ATMS系统进程的过程;
(2)ATMS向AMS发送创建应用进程的过程;
(3)AMS向Zygote进程发送创建应用进程ActivityThread的过程;
(4)Zygote进程接收请求 fork 并启动应用进程ActivityThread的过程;
(5)应用进程ActivityThread启动Activity的过程。

1.应用启动进程Launcher调用ATMS系统进程的过程

  Launcher是一个用于显示所有应用程序的一个系统级别的应用程序,也就是我们常说的桌面,通过 PackageManagerService来获取已安装的所有应用程序信息。实际上就是一个Activity,由 AMS(ActivityManagerService)来管理进程调度与启动,AMS是Android 中最核心的系统服务,几乎所有的应用都需要与AMS 通信。

  根Activity的启动流程其实就是点击Launcher中某一个应用图标到应用第一个Activity展示出来的流程,当系统开机后,Launcher也会被AMS启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击Activity中的一个Button,其相应事件就是Launcher进程请求ATMS来启动该应用程序。

1.1 时序图

AMS11.PNG

1.2 Launcher桌面的App图标入口

  从源码看一下Launcher桌面是不是如我们所说的是一个Activity,源码如下:

// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
/**
 * Default launcher application.
 */
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
        Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,
        LauncherOverlayCallbacks {
    @Override
    @TargetApi(Build.VERSION_CODES.S)
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ......
            // 分析1 -- 加载、展示布局文件
            inflateRootView(R.layout.launcher);
    }
}

/**
 * Abstract activity with state management
 * @param <STATE_TYPE> Type of state object
 */
public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
        extends BaseDraggingActivity {}

/**
 * Extension of BaseActivity allowing support for drag-n-drop
 */
@SuppressWarnings("NewApi")
public abstract class BaseDraggingActivity extends BaseActivity
        implements OnColorsChangedListener, DisplayInfoChangeListener {}

/**
 * Launcher BaseActivity
 */
public abstract class BaseActivity extends Activity implements ActivityContext {}

分析1 - 正如我们所说,Launcher就是一个Activity,加载的布局为R.layout.launcher,布局文件如下:

<!-- R.layout.launcher -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.LauncherRootView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:launcher="http://schemas.android.com/apk/res-auto"
    android:id="@+id/launcher"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.android.launcher3.dragndrop.DragLayer
        android:id="@+id/drag_layer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:importantForAccessibility="no">

        <!-- 这里是展示所有 App 图标的布局,我们只看相关代码 -->
        <include
            android:id="@+id/apps_view"
            layout="@layout/all_apps"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </com.android.launcher3.dragndrop.DragLayer>
</com.android.launcher3.LauncherRootView>
----------------------------------------------------------------
<!-- R.layout.apps_view -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.LauncherAllAppsContainerView                                         
        xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/apps_view"
    android:theme="?attr/allAppsTheme"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="true"
    android:clipToPadding="false"
    android:focusable="false"
    android:saveEnabled="false">

    <!-- 展示所有已安装app的AllAppsRecyclerView继承自RecyclerView -->
    <include
        layout="@layout/all_apps_rv_layout"
        android:visibility="gone" />

</com.android.launcher3.allapps.LauncherAllAppsContainerView>
----------------------------------------------------------------
<!-- R.layout.all_apps_rv_layout -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.AllAppsRecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/apps_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/search_container_all_apps"
    android:clipToPadding="false"
    android:descendantFocusability="afterDescendants"
    android:focusable="true" />

这下面就要看看这个AllAppsRecyclerView怎么设置适配器 Adapter,以及点击事件在哪里设置?

  AllAppsRecyclerView外层是LauncherAllAppsContainerView,它是AllAppsContainerView的子类。给 AllAppsRecyclerView设置Adapter被封装到了AllAppsContainerView里面,看一下代码:

// packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
        Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
        ScrimView.ScrimDrawingController {

        protected void rebindAdapters(boolean force) {
                ......
        if (mUsingTabs) {
            ...... 
            // 这里只分析不使用 Tabs 的情况,感兴趣的童鞋可以继续追源码
        } else {
                // AllAppsRecyclerView设置Adapter等信息
            mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
            mAH[AdapterHolder.WORK].recyclerView = null;
        }
        ......
    }        

    public class AdapterHolder {
        public static final int MAIN = 0;
        public static final int WORK = 1;

        public final AllAppsGridAdapter adapter;
        final LinearLayoutManager layoutManager;
        final AlphabeticalAppsList appsList;
        AllAppsRecyclerView recyclerView;

        AdapterHolder(boolean isWork) {
            mIsWork = isWork;
            appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore,
                    isWork ? mWorkManager.getAdapterProvider() : null);

            BaseAdapterProvider[] adapterProviders =
                    isWork ? new BaseAdapterProvider[]{mSearchAdapterProvider,
                            mWorkManager.getAdapterProvider()}
                            : new BaseAdapterProvider[]{mSearchAdapterProvider};

            // 创建adapter
            adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList,
                    adapterProviders);
            appsList.setAdapter(adapter);
            layoutManager = adapter.getLayoutManager();
        }

        void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
            appsList.updateItemFilter(matcher);
            recyclerView = (AllAppsRecyclerView) rv;
            recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
            recyclerView.setApps(appsList);
            recyclerView.setLayoutManager(layoutManager);
            // AllAppsRecyclerView 设置 AllAppsGridAdapter
            recyclerView.setAdapter(adapter);
        }
    }
}

源码中在AllAppsContainerView中为AllAppsRecyclerView设置了AllAppsGridAdapter,然后在AllAppsGridAdapter #onCreateViewHolder()方法中为子项itemView设置点击事件,点击事件由launcher.getItemOnClickListener()方法获取(BaseDraggingActivity.java#ItemClickHandler.INSTANCE)。看一下ItemClickHandler是怎么处理点击事件的,代码如下:

// packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
public class ItemClickHandler {
    private static final String TAG = ItemClickHandler.class.getSimpleName();
    /**
     * Instance used for click handling on items
     * 单例方式获取点击事件
     */
    public static final OnClickListener INSTANCE = ItemClickHandler::onClick;

    private static void onClick(View v) {
        if (v.getWindowToken() == null) return;
        Launcher launcher = Launcher.getLauncher(v.getContext());
        if (!launcher.getWorkspace().isFinishedSwitchingState()) return;

        Object tag = v.getTag();
        if (tag instanceof WorkspaceItemInfo) {
            onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);
        } else if (tag instanceof FolderInfo) {
            if (v instanceof FolderIcon) {
                onClickFolderIcon(v);
            }
        } else if (tag instanceof AppInfo) {
                // 点击 App 图标
            startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher
            );
        } else if (tag instanceof LauncherAppWidgetInfo) {
            if (v instanceof PendingAppWidgetHostView) {
                onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
            }
        } else if (tag instanceof SearchActionItemInfo) {
            onClickSearchAction(launcher, (SearchActionItemInfo) tag);
        }
    }
---------------------------------------------------
    private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
        Intent intent;
        if (item instanceof ItemInfoWithIcon
                && (((ItemInfoWithIcon) item).runtimeStatusFlags
                & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
            ItemInfoWithIcon appInfo = (ItemInfoWithIcon) item;
            intent = new PackageManagerHelper(launcher)
                    .getMarketIntent(appInfo.getTargetComponent().getPackageName());
        } else {
            intent = item.getIntent();
        }
        if (intent == null) {
            throw new IllegalArgumentException("Input must have a valid intent");
        }
        if (item instanceof WorkspaceItemInfo) {
            WorkspaceItemInfo si = (WorkspaceItemInfo) item;
            if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
                    && Intent.ACTION_VIEW.equals(intent.getAction())) {
                intent = new Intent(intent);
                intent.setPackage(null);
            }
            if ((si.options & WorkspaceItemInfo.FLAG_START_FOR_RESULT) != 0) {
                launcher.startActivityForResult(item.getIntent(), 0);
                InstanceId instanceId = new InstanceIdSequence().newInstanceId();
                launcher.logAppLaunch(launcher.getStatsLogManager(), item, instanceId);
                return;
            }
        }
        if (v != null && launcher.supportsAdaptiveIconAnimation(v)) {
            // Preload the icon to reduce latency b/w swapping the floating view with the original.
            FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
        }
        // 调用Launcher#startActivitySafely()启动Activity
        launcher.startActivitySafely(v, intent, item);
    }
}

回答上面的问题,AllAppsRecyclerView在AllAppsContainerView中设置了AllAppsGridAdapter,在 AllAppsGridAdapter#onCreateViewHolder() 方法中为子项itemView设置点击事件 ItemClickHandler.INSTANCE。

1.3 Launcher#startActivitySafely()

  下面回到Launcher这个Activity中看一下startActivitySafely()方法,代码如下:

// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
        Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,
        LauncherOverlayCallbacks {
    @Override
    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        if (!hasBeenResumed()) {
            addOnResumeCallback(() -> startActivitySafely(v, intent, item));
            if (mOnDeferredActivityLaunchCallback != null) {
                mOnDeferredActivityLaunchCallback.run();
                mOnDeferredActivityLaunchCallback = null;
            }
            return true;
        }

        // 调用父类的startActivitySafely()方法
        boolean success = super.startActivitySafely(v, intent, item);
        if (success && v instanceof BubbleTextView) {
            BubbleTextView btv = (BubbleTextView) v;
            btv.setStayPressed(true);
            addOnResumeCallback(() -> btv.setStayPressed(false));
        }
        return success;
    }
}
------------------------------------------
// 继承关系:Launcher =》StatefulActivity=》BaseDraggingActivity
public abstract class BaseDraggingActivity extends BaseActivity
        implements OnColorsChangedListener, DisplayInfoChangeListener {

    public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
        ......
        Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
        UserHandle user = item == null ? null : item.user;
        // Prepare intent
        // 添加 FLAG_ACTIVITY_NEW_TASK,即在新的Task中启动 Activity
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(Utilities.getViewBounds(v));
        }
        try {
            boolean isShortcut = (item instanceof WorkspaceItemInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((WorkspaceItemInfo) item).isPromise();
            if (isShortcut) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                // 点击App图标 启动 App
                startActivity(intent, optsBundle);
            } else {
                getSystemService(LauncherApps.class).startMainActivity(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            if (item != null) {
                InstanceId instanceId = new InstanceIdSequence().newInstanceId();
                logAppLaunch(getStatsLogManager(), item, instanceId);
            }
            return true;
        } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
            ......
        }
        return false;
    }
}

根Activity启动时,添加FLAG_ACTIVITY_NEW_TASK,即在新的任务栈Task中启动Activity,然后调⽤到Activity# startActivity()⽅法,传⼊参数为intent和Bundle。代码如下:

// frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
        implements ... {

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        ......
        if (options != null) {
                // 通过startActivityForResult启动Activity
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        // mParent 表示当前Activity的父 Activity,一般情况下mParent为空
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }
            cancelInputsAndStartExitTransition(options);
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
}

Activity#startActivity()方法调用Activity#startActivityForResult()方法,Activity#startActivity()第二个参数为-1表示Launcher不需要知道根Activity的启动结果。由于mParent=null(mParent表示当前Activity的父Activity,一般情况下mParent为空),所以我们只需要关注mParent=null的情况,此时会调用Instrumentation#execStartActivity() 方法。

1.4 Instrumentation#execStartActivity()

  Instrumentation负责调用Activity和Application的生命周期,每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。跟进去看看Instrumentation#execStartActivity()方法,代码如下:

// frameworks/base/core/java/android/app/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);
            // 获取ActivityTaskManagerService的代理对象
            int result = ActivityTaskManager.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) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

Instrumentation#execStartActivity()方法会调用ActivityTaskManager#getService()方法来获取ActivityTaskManagerService的代理对象,然后调用这个代理对象的startActivity()方法。

 // frameworks/base/core/java/android/app/ActivityTaskManager.java
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    // 获取ActivityTaskManagerService的引用
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    // 返回一个代理对象
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };

在Singleton的create()方法中,获取ActivityTaskManagerService的引用,这是一个IBinder类型的引用,且 ActivityTaskManagerService作为服务端处于system_server进程,与当前作为客户端的Launcher进程不在同一个进程。 所以这里方法返回的是IActivityTaskManager.Stub的代理对象,而ActivityTaskManagerService则是对应的实现类,继承了IActivityTaskManager.Stub并实现相应的方法,通过代理对象可以跨进程调用服务端ActivityTaskManagerService的方法。

2.ATMS向AMS发送创建应用进程的过程

  system_server进程中startBootstrapServices()方法启动系统引导服务,引导服务中启动了ATM(ActivityTaskManagerService)、AMS 等服务,其中ATMS是Android 10中新增的,本来都是AMS来管理,Google 考虑到AMS职责太多、代码太庞大,所以单独拆出来ATMS用于管理Activity及其容器类,如Task、Stack、Display 等,分担AMS部分职责。

2.1 时序图

AMS12.png

2.2 ATMS(ActivityTaskManagerService)

  通过上面的分析,启动过程走到了ATMS中,调用ATMS#startActivity()方法,代码如下:

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) {
        // UserHandle.getCallingUserId()方法会获取调用者的UserId
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    @Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        // 继续调用startActivityAsUser
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        // 检查调用者的进程是否隔离,如果isIsolated则抛出SecurityException异常
        enforceNotIsolatedCaller("startActivityAsUser");
        // 检查调用者权限,ATMS根据传入的UserId来确定调用者的权限
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        // 获取ActivityStarter,然后调用它的execute()执行启动Activity的过程
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller) // 配置启动的参数
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute(); // 执行启动任务
    }

    // 获取ActivityStartController
    ActivityStartController getActivityStartController() {
        return mActivityStartController;
    }

2.3 ActivityStartController

    // frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
    /**
     * @return A starter to configure and execute starting an activity. It is valid until after
     *         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
     *         considered invalid and no longer modified or used.
     */
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

获取ActivityStarter对象后通过Builder模式设置启动所需的各种参数值,然后执行启动Activity。ActivityStarter是 Android 7.0中增加的,用来加载启动Activity的控制类。

2.4 ActivityStarter

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
class ActivityStarter {
    @VisibleForTesting
    interface Factory {
        // Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
        void setController(ActivityStartController controller);

        // 生成一个准备处理新启动请求的ActivityStarter,ActivityStartController持有这个实例对象
        ActivityStarter obtain();

        // Recycles a starter for reuse.
        void recycle(ActivityStarter starter);
    }
-----------------------------------------------------------
    // Default implementation of {@link StarterFactory}.
    static class DefaultFactory implements Factory {
        // 被激活的启动器的最大数
        private final int MAX_STARTER_COUNT = 3;

        private ActivityStartController mController;
        private ActivityTaskManagerService mService;
        private ActivityStackSupervisor mSupervisor;
        private ActivityStartInterceptor mInterceptor;

        private SynchronizedPool<ActivityStarter> mStarterPool =
                new SynchronizedPool<>(MAX_STARTER_COUNT);

        DefaultFactory(ActivityTaskManagerService service,
                ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
            mService = service;
            mSupervisor = supervisor;
            mInterceptor = interceptor;
        }

        @Override
        public void setController(ActivityStartController controller) {
            mController = controller;
        }

        @Override
        public ActivityStarter obtain() {
            // 直接获取已有的ActivityStarter
            ActivityStarter starter = mStarterPool.acquire();
            if (starter == null) {
                // 如果没有获取到已有的,就新创建一个
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }
            return starter;
        }

        @Override
        public void recycle(ActivityStarter starter) {
            starter.reset(true /* clearRequest*/);
            mStarterPool.release(starter);
        }
    }
 -----------------------------------------------------------   
    /**
     * Resolve necessary information according the request parameters provided earlier, and execute
     * the request which begin the journey of starting an activity.
     * @return The starter result.
     */
    int execute() {
        try {
            int res;
            synchronized (mService.mGlobalLock) {
                final boolean globalConfigWillChange = mRequest.globalConfig != null
                        && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
                if (stack != null) {
                    stack.mConfigWillChange = globalConfigWillChange;
                }

                final long origId = Binder.clearCallingIdentity();

                res = resolveToHeavyWeightSwitcherIfNeeded();
                if (res != START_SUCCESS) {
                    return res;
                }
                // 继续调用executeRequest()方法
                res = executeRequest(mRequest);
                Binder.restoreCallingIdentity(origId);
                if (globalConfigWillChange) {
                    ......
                    mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
                }

                // Notify ActivityMetricsLogger that the activity has launched.
                // ActivityMetricsLogger will then wait for the windows to be drawn and populate
                // WaitResult.
                mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                        mLastStartActivityRecord);
                return getExternalResult(mRequest.waitResult == null ? res
                        : waitForResult(res, mLastStartActivityRecord));
            }
        } finally {
            onExecutionComplete();
        }
    }
-----------------------------------------------------------
    private int executeRequest(Request request) {
                ......
                // 创建 ActivityRecord,保存 Activity 的所有信息
                final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, callingFeatureId, intent, resolvedType, aInfo,
                mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
                request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
                sourceRecord);
        mLastStartActivityRecord = r;
        ......
        final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
        // 继续调用startActivityUnchecked()方法
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);
                ......
        return mLastStartActivityResult;
    }
-----------------------------------------------------------
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        int result = START_CANCELED;
        try {
            mService.deferWindowLayout();
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } 
        ......
        return result;
    }
-----------------------------------------------------------
    @VisibleForTesting
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        ......
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                                ......
                mTargetStack.ensureActivitiesVisible(null /* starting */,
                        0 /* configChanges */, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                ......
                // 启动流程交给mRootWindowContainer的resumeFocusedStacksTopActivities()
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        }
    }
}
  1. 在上面的第一步中获取ActivityStartController,调用其obtainStarter()方法,通过内部实现的DefaultFactory来获取 ActivityStarter,如果在mStarterPool中没有获取到,则新创建一个。

  2. 上面介绍了ActivityStarter类是用来加载启动Activity的控制类,在ActivityStarter#execute() 方法中,会继续调用 ActivityStarter#executeRequest() 方法,这里会处理启动Activity的请求,并开始一个Activity 启动的流程。

  3. ActivityStarter#executeRequest()方法会进行初步的检查并且确认权限,并且在这里组装对应Activity的ActivityRecord,其包含了对应Activity的所有信息,并储存在任务栈TaskRecord中。在Activity的启动过程中,Activity都是通过ActivityRecord来表示的。然后继续调用ActivityStarter#startActivityUnchecked() 方法,接着 ActivityStarter#startActivityUnchecked()方法会调用ActivityStarter#startActivityInner()方法。

  4. 在ActivityStarter#startActivityInner()方法中,主要就是处理Activity的启动模式有关的逻辑,并且在ActivityStack中处理对应Activity在任务栈中的相关事宜,包括但不限于将对应的ActivityRecord添加到TaskRecord栈中、将对应的ActivityRecord提到TaskRecord栈中最顶部。

  5. 最后调用 RootWindowContainer#resumeFocusedStacksTopActivities()方法,将启动流程交给RootWindowContainer处理。

2.5 RootWindowContainer

// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        ......
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackInDisplayArea()
                || getTopDisplayFocusedStack() == targetStack)) {
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            boolean resumedOnDisplay = false;
            ......
            if (!resumedOnDisplay) {
                // In cases when there are no valid activities (e.g. device just booted or launcher
                // crashed) it's possible that nothing was resumed on a display. Requesting resume
                // of top activity in focused stack explicitly will make sure that at least home
                // activity is started and resumed, and no recursion occurs.
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    // focusedStack不为空的时候,调用ActivityStack的方法
                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                } else if (targetStack == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
        }

        return result;
    }

RootWindowContainer是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。

  RootWindowContainer#resumeFocusedStacksTopActivities()方法会恢复对应任务栈顶部的Activity,方法中会检查一些可见性相关的属性,后转交给ActivityStack#resumeTopActivityUncheckedLocked() 方法来继续启动流程。

2.6 ActivityStack

// frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
    @GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;
            // 直接调用内部方法
            result = resumeTopActivityInnerLocked(prev, options);

            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
            // to ensure any necessary pause logic occurs. In the case where the Activity will be
            // shown regardless of the lock screen, the call to
            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return result;
    }
----------------------------------------------------------
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
                if (next.attachedToProcess()) {
                        ......
            ActivityRecord lastResumedActivity =
                    lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
            final ActivityState lastState = next.getState();

            next.setState(RESUMED, "resumeTopActivityInnerLocked");

            next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                    true /* activityChange */, true /* updateOomAdj */,
                    true /* addPendingTopUid */);

            // From this point on, if something goes wrong there is no way
            // to recover the activity.
            try {
                next.completeResumeLocked();
            } catch (Exception e) {
                ......
                mStackSupervisor.startSpecificActivity(next, true, false);
                return true;
            }
        } else {
            // Whoops, need to restart this activity!
            ......
        }
        return true;
        }

ActivityStack是一个管理类,用来管理系统所有Activity的各种状态,其内部维护了TaskRecord的列表,每个TaskRecord又包含了若干个ActivityRecord,每个ActivityRecord对应了一个Activity。这里TaskRecord相当于在启动模式中的“任务栈”,根据启动模式的不同,在启动Activity的时候,会对TaskRecord进行不同的操作。

  由于前一步已经将对应Activity的ActivityRecord 添加到了栈顶,所以ActivityStack#resumeTopActivityUncheckedLocked() 方法恢复的就是将启动的栈顶Activity,然后继续调用 ActivityStack#resumeTopActivityInnerLocked()方法来继续启动流程,该方法中做了一系列判断,确保待启动 Activity可见性、预定Activity的切换动画等。后转交给ActivityStackSupervisor#startSpecificActivity()方法来启动栈顶特定的Activity。

2.7 ActivityStackSupervisor

// frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        // 获取即将要启动的 Activity 的所在的应用程序进程已经运行了吗?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        boolean knownToBeDead = false;
        // wpc.hasThread() 内部通过判断 IApplicationThread 是否被赋值,如果已赋值,即应用进程已运行
        // 启动 Activity 的应用程序进程已经创建运行则走 Activity 的生命周期
        // 即普通 Activity 的启动走 realStartActivityLocked() 方法继续 Activity 的创建
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                ......
            }
            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }
        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        // 如果未赋值,即应用进程还不存在,则需要创建应用进程,由于是根 Activity 的启动所以应用进程还未被创建并启动
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

ActivityStackSupervisor是用来辅助ATMS对Activity和Task进行管理的,其中ActivityStackSupervisor是对ActivityStack进行管理的,用ActivityStack对Acitivity进行状态管理。

  ActivityStackSupervisor内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个ActivityStack:

  • mHomeStack管理的是Launcher相关的Activity栈,stackId为0。
  • mFocusedStack管理的是当前显示在前台Activity的Activity 栈。
  • mLastFocusedStack管理的是上一次显示在前台Activity 的Activity栈。

  ActivityStackSupervisor#startSpecificActivity()方法中获取WindowProcessController ,通过wpc#hasThread()方法判断应用进程是否已创建并运行中,其内部是通过IApplicationThread是否已经被赋值来判断的,如果已被赋值则表示应用进程已创建且运行中,此时进入判断体内部,走ActivityStackSupervisor#realStartActivityLocked() 方法继续Activity的启动流程,即普通Activity的启动流程。如果未被赋值,则需要创建应用进程,这里由于是根Activity的启动所以应用进程还未被创建并启动。

  留个小问题,WindowProcessController#IApplicationThread是何时、在哪里赋值的?(下一篇继续)

相关文章

网友评论

      本文标题:Android ActivityManagerService--

      本文链接:https://www.haomeiwen.com/subject/wvpvvdtx.html