本文基于android13-release源码浏览整顿

零碎源码地址:init.h - Android Code Search

1.前言

紧接上篇[Android零碎Launcher启动流程)]咱们持续看看Launcher是如何运行并加载所有桌面利用,继而探索用户在launcher桌面点击App图标启动利用整体流程

2.Launcher运行及生命周期办法

相熟Android开发的同学在启动模拟器显示桌面后,咱们能够直观看到模拟器顶部搜寻框,工夫日历小部件,可拖拽利用区域,底部导航批示条以及快捷启动图标,利用文件夹等,基于零碎UI层级展现形式,咱们通过源码逐渐探寻其工作形式.上面咱们从onCreate()函数开始

源码地位:packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

2.1 Launcher.onCreate

protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    //获取LauncherAppState实例,次要解决IconCache,IconCacheProvider、LauncherModel对象初始化及凋谢对外调用办法    LauncherAppState app = LauncherAppState.getInstance(this);    mOldConfig = new Configuration(getResources().getConfiguration());    //LauncherAppState中定义对外调用办法    mModel = app.getModel();    mRotationHelper = new RotationHelper(this);    //依据屏幕宽高读取最靠近设施文件信息,用于桌面图标大小,行列数配置    InvariantDeviceProfile idp = app.getInvariantDeviceProfile();    initDeviceProfile(idp);    idp.addOnChangeListener(this);    //存储库SharePreferences    mSharedPrefs = Utilities.getPrefs(this);    mIconCache = app.getIconCache();    mAccessibilityDelegate = createAccessibilityDelegate();    //初始化拖拽布局控制器    mDragController = new LauncherDragController(this);    //解决所有app在桌面拖拽图标时的动画    mAllAppsController = new AllAppsTransitionController(this);    mStateManager = new StateManager < >(this, NORMAL);    //关联存储库SharePreferences    mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);    //小部件治理helper    mAppWidgetManager = new WidgetManagerHelper(this);    mAppWidgetHost = createAppWidgetHost();    mAppWidgetHost.startListening();    //加载launcher xml    inflateRootView(R.layout.launcher);    //设置所有apps view,放在上面大节独自剖析    setupViews();    //淡入淡出动画    crossFadeWithPreviousAppearance();    //设置监听NotificationListener,PopupDataProvider次要解决长按app图标显示内容    mPopupDataProvider = new PopupDataProvider(this: :updateNotificationDots);    //状态解决相干    boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this);    if (internalStateHandled) {        if (savedInstanceState != null) {            // InternalStateHandler has already set the appropriate state.            // We dont need to do anything.            savedInstanceState.remove(RUNTIME_STATE);        }    }    restoreState(savedInstanceState);    mStateManager.reapplyState();    if (savedInstanceState != null) {        int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);        if (pageIds != null) {            mPagesToBindSynchronously = IntSet.wrap(pageIds);        }    }    //LoaderTask相干操作,放在上面大节独自剖析    if (!mModel.addCallbacksAndLoad(this)) {        if (!internalStateHandled) {            Log.d(BAD_STATE, "Launcher onCreate not binding sync, prevent drawing");            // If we are not binding synchronously, pause drawing until initial bind complete,            // so that the system could continue to show the device loading prompt            mOnInitialBindListener = Boolean.FALSE: :booleanValue;        }    }    // For handling default keys    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);    //设置页面布局    setContentView(getRootView());    if (mOnInitialBindListener != null) {        getRootView().getViewTreeObserver().addOnPreDrawListener(mOnInitialBindListener);    }    getRootView().dispatchInsets();    //注册屏幕敞开播送监听    registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));    //更新UiState、Theme(Dark/Light)    getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));    //hook生命周期办法    if (mLauncherCallbacks != null) {        mLauncherCallbacks.onCreate(savedInstanceState);    }    mOverlayManager = getDefaultOverlay();    PluginManagerWrapper.INSTANCE.get(this).addPluginListener(this, LauncherOverlayPlugin.class, false    /* allowedMultiple */    );    //屏幕旋转切换配置初始化    mRotationHelper.initialize();    TraceHelper.INSTANCE.endSection(traceToken);    mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(() - >getStateManager().goToState(NORMAL));    if (Utilities.ATLEAST_R) {        getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING);    }    setTitle(R.string.home_screen);}

launcher类中onCreate()会初始化LauncherAppState实例,用于获取Icon/LauncherModel对象,读取设施文件信息以匹配桌面图标及行列数,初始化SharedPreferences,布局拖拽控制器,设置布局xml,apps view,以及LoaderTask相干操作,设置页面布局及其它配置信息,上面咱们来看看源码中setupViews()办法

2.2 Launcher.setupViews()

protected void setupViews() {    //加载根布局    inflateRootView(R.layout.launcher);    mDragLayer = findViewById(R.id.drag_layer);    mFocusHandler = mDragLayer.getFocusIndicatorHelper();    mWorkspace = mDragLayer.findViewById(R.id.workspace);    //初始化PageIndicator    mWorkspace.initParentViews(mDragLayer);    mOverviewPanel = findViewById(R.id.overview_panel);    mHotseat = findViewById(R.id.hotseat);    //设置快捷启动图标工作区    mHotseat.setWorkspace(mWorkspace);    // Setup the drag layer    mDragLayer.setup(mDragController, mWorkspace);    //初始化DragController,更新layer type属性    mWorkspace.setup(mDragController);    //绑定工作区之前锁定壁纸默认状态    mWorkspace.lockWallpaperToDefaultPage();    //初始化第一页并绑定,此处会以CellLayout承载页面,其自身继承于ViewGroup,反对对item拖入拖出操作    mWorkspace.bindAndInitFirstWorkspaceScreen();    //拖拽监听    mDragController.addDragListener(mWorkspace);    // Get the search/delete/uninstall bar    mDropTargetBar = mDragLayer.findViewById(R.id.drop_target_bar);    // Setup Apps    mAppsView = findViewById(R.id.apps_view);    // Setup Scrim    mScrimView = findViewById(R.id.scrim_view);    // Setup the drag controller (drop targets have to be added in reverse order in priority)    mDropTargetBar.setup(mDragController);    //mAppsView设置mScrimView    mAllAppsController.setupViews(mScrimView, mAppsView);}

以上办法初始化相干views并设置监听,上面咱们再看LoaderTask数据加载是如何进行的
源码门路:packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

2.3 LoaderTask

public boolean addCallbacksAndLoad(@NonNull final Callbacks callbacks) {    synchronized(mLock) {        addCallbacks(callbacks);        return startLoader(new Callbacks[] {            callbacks        });    }}private boolean startLoader(@NonNull final Callbacks[] newCallbacks) {    // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems    ItemInstallQueue.INSTANCE.get(mApp.getContext()).pauseModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING);    synchronized(mLock) {        //进行LoaderTask工作线程        boolean wasRunning = stopLoader();        //设置相干标记        boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;        boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;        final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;        if (callbacksList.length > 0) {            //同步工作执行时革除任意挂起绑定操作            for (Callbacks cb: callbacksList) {                MAIN_EXECUTOR.execute(cb: :clearPendingBinds);            }            //构建loaderResults            LoaderResults loaderResults = new LoaderResults(mApp, mBgDataModel, mBgAllAppsList, callbacksList);            if (bindDirectly) {                // Divide the set of loaded items into those that we are binding synchronously,                // and everything else that is to be bound normally (asynchronously).                loaderResults.bindWorkspace(bindAllCallbacks);                // For now, continue posting the binding of AllApps as there are other                // issues that arise from that.                loaderResults.bindAllApps();                loaderResults.bindDeepShortcuts();                loaderResults.bindWidgets();                return true;            } else {                stopLoader();                //构建LoaderTask工作并筹备执行                mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);                // Always post the loader task, instead of running directly                // (even on same thread) so that we exit any nested synchronized blocks                //通过handler公布mLoaderTask,但不以內联形式运行                MODEL_EXECUTOR.post(mLoaderTask);            }        }    }    return false;}

通过下面代码调用链,此时mLoaderTask曾经公布,咱们看下LoaderTask.run()具体执行内容有哪些

public void run() {    ...    ...    LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();    try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {        List < ShortcutInfo > allShortcuts = new ArrayList < >();        try {            //加载工作区            loadWorkspace(allShortcuts, memoryLogger);        } finally {            Trace.endSection();        }        ...        //绑定工作区        mResults.bindWorkspace(true /* incrementBindId */);        mModelDelegate.workspaceLoadComplete();        //发送首屏播送告诉,告诉软件安装包在首屏无效装置        sendFirstScreenActiveInstallsBroadcast();        //期待workspace加载实现        waitForIdle();        ...        List < LauncherActivityInfo > allActivityList;        try {            //加载所有apps,从缓存读取user profiles,清空利用列表,依据profile读取所有LauncherActivityInfo,最终增加进缓存汇合            allActivityList = loadAllApps();        } finally {            Trace.endSection();        }        ...        //绑定所有apps        mResults.bindAllApps();        ...        //获取解决图标缓存更新handler        IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();        setIgnorePackages(updateHandler);        updateHandler.updateIcons(allActivityList, LauncherActivityCachingLogic.newInstance(mApp.getContext()), mApp.getModel() : :onPackageIconsUpdated);        ...        //缓存allShortcuts        updateHandler.updateIcons(allShortcuts, new ShortcutCachingLogic(), mApp.getModel() : :onPackageIconsUpdated);        //期待上述步骤操作实现        waitForIdle();        ...        //加载应用程序快捷方式        List < ShortcutInfo > allDeepShortcuts = loadDeepShortcuts();        ...        //绑定利用快捷启动形式        mResults.bindDeepShortcuts();        ...        //缓存allDeepShortcuts        updateHandler.updateIcons(allDeepShortcuts, new ShortcutCachingLogic(), (pkgs, user) - >{});        //期待上述步骤操作实现        waitForIdle();        ...        //加载桌面小部件allWidgetsList        List < ComponentWithLabelAndIcon > allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null);        ...        //绑定桌面小部件        mResults.bindWidgets();        ...        //缓存小部件图标        updateHandler.updateIcons(allWidgetsList, new ComponentWithIconCachingLogic(mApp.getContext(), true), mApp.getModel() : :onWidgetLabelsUpdated);        ...        //加载桌面文件夹名称        loadFolderNames();        ...        //解决实现        updateHandler.finish();        mModelDelegate.modelLoadComplete();        transaction.commit();        memoryLogger.clearLogs();    } catch(CancellationException e) {        // Loader stopped, ignore        logASplit(logger, "Cancelled");    } catch(Exception e) {        memoryLogger.printLogs();        throw e;    } finally {        logger.dumpToLog();    }    TraceHelper.INSTANCE.endSection(traceToken);}

在LoaderTask.run()中能够清晰看到加载数据的每一步操作,基于此launcher桌面利用相干信息根本加载实现,Launcher类自身继承于StatefulActivity,其生命周期办法与惯例Activity基本一致,感兴趣的可持续在源码外面查看相干办法具体解决内容

3.点击桌面图标启动App

3.1 bindWorkspace与createShortcut

上述步骤中在loadWorkspace()之后紧接着调用bindWorkpsace(),用于将所有加载数据绑定到主线程上的理论视图

public void bindWorkspace(boolean incrementBindId) {    ...    ...    for (Callbacks cb: mCallbacksList) {        new WorkspaceBinder(cb, mUiExecutor, mApp, mBgDataModel, mMyBindingId, workspaceItems, appWidgets, extraItems, orderedScreenIds).bind();    }}

次要看下bind()办法,会持续调用bindWorkspaceItems(),用于最终callback调用bindItems,此处callback对象为launcher实例,Launcher中定义了bindItems()
//该办法中会循环调用view = createShortcut(info)创立view,createShortcut()也同样定义在Launcher类中,

private void bindWorkspaceItems(final ArrayList < ItemInfo > workspaceItems, final Executor executor) {    // Bind the workspace items    int count = workspaceItems.size();    for (int i = 0; i < count; i += ITEMS_CHUNK) {        final int start = i;        final int chunkSize = (i + ITEMS_CHUNK <= count) ? ITEMS_CHUNK: (count - i);        executeCallbacksTask(c - >c.bindItems(workspaceItems.subList(start, start + chunkSize), false), executor);    }}//创立shortcutpublic View createShortcut(ViewGroup parent, WorkspaceItemInfo info) {    BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.app_icon, parent, false);    favorite.applyFromWorkspaceItem(info);    //设置图标点击事件,ItemClickHandler用于解决对工作区和所有利用点击响应    favorite.setOnClickListener(ItemClickHandler.INSTANCE);    favorite.setOnFocusChangeListener(mFocusHandler);    return favorite;}//点击事件响应private static void onClick(View v) {    ...    ...    Object tag = v.getTag();    //起源来为WorkspaceItemInfo,    if (tag instanceof WorkspaceItemInfo) {        //持续调用startAppShortcutOrInfoActivity(v, shortcut, launcher)用于启动activity        onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);    }    ...    ...}//启动activityprivate static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {        //构建intent        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 (item instanceof WorkspaceItemInfo) {            WorkspaceItemInfo si = (WorkspaceItemInfo) item;            if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)                    && Intent.ACTION_VIEW.equals(intent.getAction())) {the                // web ui. This only works though if the package isn't set                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;            }        }        ...        //启动activity        launcher.startActivitySafely(v, intent, item);    }}

通过startActivitySafely启动activity,咱们须要看下Launcher继承关系,

Launcher->StatefulActivity->BaseDraggingActivity->BaseActivity implements AppLauncher,
所以launcher.startActivitySafely最终是调用AppLauncher接口中的同名办法,该办法会构建利用启动须要的显示
的宽高参数、animation、displayId,封装到Bundle对象中,最初调用startShortcut(),办法源码如下:

3.2 startShortcut

default void startShortcut(String packageName, String id, Rect sourceBounds, Bundle startActivityOptions, UserHandle user) {    if (GO_DISABLE_WIDGETS) {        return;    }    try {         ((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id, sourceBounds, startActivityOptions, user);    } catch(SecurityException | IllegalStateException e) {            Log.e(TAG, "Failed to start shortcut", e);    }}//通过一系列参数解决最终走到LauncherApps.java中,源码地位:frameworks/base/core/java/android/content/pm/LauncherApps.java@UnsupportedAppUsage private void startShortcut(@NonNull String packageName, @NonNull String shortcutId, @Nullable Rect sourceBounds, @Nullable Bundle startActivityOptions, int userId) {    try {        //此处mService对应LauncherAppsImpl实现类,通过aidl定义实现用于跨过程通信        final boolean success = mService.startShortcut(mContext.getPackageName(), packageName, null        /* default featureId */        , shortcutId, sourceBounds, startActivityOptions, userId);        if (!success) {            throw new ActivityNotFoundException("Shortcut could not be started");        }    } catch(RemoteException e) {        throw e.rethrowFromSystemServer();    }}

@SystemService(Context.LAUNCHER_APPS_SERVICE)通过注解标记零碎服务,当作用于类是可便捷获取其服务实例,此处LAUNCHER_APPS_SERVICE对应实例类LauncherAppService.java类

在被注解的LauncherApps类可通过context.getSystemService获取,具体代码位于该类构造函数中;LauncherAppsService构造函数初始化了LauncherAppsImpl实例,在onStart启动服务办法中公布了LAUNCHER_APPS_SERVICE标记服务

LauncherAppsImpl实例中定义了startShortcut()办法,最终调用startShortcutInner()验证调用包,用户是否有权限拜访配置文件以及异步创立快捷方式启动intent,并配置intent启动标记,源边界及Splash theme,最初调用startShortcutIntentsAsPublisher()启动activity,

3.3 startShortcutInner

其源码如下

//源码地位:/frameworks/base/services/core/java/com/android/server/pm/LauncherAppsService.javaprivate boolean startShortcutInner(int callerUid, int callerPid, int callingUserId, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {    verifyCallingPackage(callingPackage, callerUid);    if (!canAccessProfile(targetUserId, "Cannot start activity")) {        return false;    }    if (!mShortcutServiceInternal.isPinnedByCaller(callingUserId, callingPackage, packageName, shortcutId, targetUserId)) {        ensureShortcutPermission(callerUid, callerPid, callingPackage);    }    final AndroidFuture < Intent[] > ret = new AndroidFuture < >();    Intent[] intents;    mShortcutServiceInternal.createShortcutIntentsAsync(getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId, injectBinderCallingPid(), injectBinderCallingUid(), ret);    try {        intents = ret.get();    } catch(InterruptedException | ExecutionException e) {        return false;    }    if (intents == null || intents.length == 0) {        return false;    }    ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);    if (options != null && options.isApplyActivityFlagsForBubbles()) {        // Flag for bubble to make behaviour match documentLaunchMode=always.        intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);        intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);    }    intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    intents[0].setSourceBounds(sourceBounds);    final String splashScreenThemeResName = mShortcutServiceInternal.getShortcutStartingThemeResName(callingUserId, callingPackage, packageName, shortcutId, targetUserId);    if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) {        if (startActivityOptions == null) {            startActivityOptions = new Bundle();        }        startActivityOptions.putString(KEY_SPLASH_SCREEN_THEME, splashScreenThemeResName);    }    return startShortcutIntentsAsPublisher(intents, packageName, featureId, startActivityOptions, targetUserId);}private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents, @NonNull String publisherPackage, @Nullable String publishedFeatureId, Bundle startActivityOptions, int userId) {    final int code;    try {        //mActivityTaskManagerInternal - ActivityTaskManagerService的外部抽象类        code = mActivityTaskManagerInternal.startActivitiesAsPackage(publisherPackage, publishedFeatureId, userId, intents, startActivityOptions);        if (ActivityManager.isStartResultSuccessful(code)) {            return true; // Success        } else {            Log.e(TAG, "Couldn't start activity, code=" + code);        }        return false;    } catch(SecurityException e) {        if (DEBUG) {            Slog.d(TAG, "SecurityException while launching intent", e);        }        return false;    }}

在LauncherAppsImpl构造函数中,会通过LocalServices.getService(ActivityTaskManagerInternal.class)获取ActivityTaskManagerInternal实例

那该实例何时被增加进去的呢,这个就须要看ActivityTaskManagerService中的start()办法,其中定义了外部类LocalService继承于ActivityTaskManagerInternal抽象类,最终调用
startActivitiesAsPackage()

//源码地位:/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java@Override public int startActivitiesAsPackage(String packageName, @Nullable String featureId, int userId, Intent[] intents, Bundle bOptions) {    Objects.requireNonNull(intents, "intents");    final String[] resolvedTypes = new String[intents.length];    // UID of the package on user userId.    // "= 0" is needed because otherwise catch(RemoteException) would make it look like    // packageUid may not be initialized.    int packageUid = 0;    final long ident = Binder.clearCallingIdentity();    try {        for (int i = 0; i < intents.length; i++) {            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());        }        packageUid = AppGlobals.getPackageManager().getPackageUid(packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);    } catch(RemoteException e) {        // Shouldn't happen.    } finally {        Binder.restoreCallingIdentity(ident);    }    return getActivityStartController().startActivitiesInPackage(packageUid, packageName, featureId, intents, resolvedTypes, null    /* resultTo */    , SafeActivityOptions.fromBundle(bOptions), userId, false    /* validateIncomingUser */    , null    /* originatingPendingIntent */    , false    /* allowBackgroundActivityStart */    );}

能够看到最重要的一行:getActivityStartController().startActivitiesInPackage()交由ActivityStartController治理启动activity相干操作,在上一篇博文中
7.AMS.systemReady办法启动Launcher也会波及ActivityStartController执行executeRequest,

3.4 startActivitiesInPackage

咱们持续看下调用办法源码,

//源码地位:/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.javafinal int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {    final String reason = "startActivityInPackage";    //校验指标用户id,并保障不是非凡用户    userId = checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), reason);    //筹备启动    return startActivities(null, uid, realCallingPid, realCallingUid, callingPackage, callingFeatureId, intents, resolvedTypes, resultTo, options, userId, reason, originatingPendingIntent, allowBackgroundActivityStart);}//最终调用启动办法int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid, int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, String reason, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {    ...    ...    try {        intents = ArrayUtils.filterNotNull(intents, Intent[] : :new);        ...        ...        final IBinder sourceResultTo = resultTo;        final ActivityRecord[] outActivity = new ActivityRecord[1];        // Lock the loop to ensure the activities launched in a sequence.        synchronized(mService.mGlobalLock) {            mService.deferWindowLayout();            // To avoid creating multiple starting window when creating starting multiples            // activities, we defer the creation of the starting window once all start request            // are processed            mService.mWindowManager.mStartingSurfaceController.beginDeferAddStartingWindow();            try {                for (int i = 0; i < starters.length; i++) {                    final int startResult = starters[i].setResultTo(resultTo).setOutActivity(outActivity).execute();                    if (startResult < START_SUCCESS) {                        // Abort by error result and recycle unused starters.                        for (int j = i + 1; j < starters.length; j++) {                            mFactory.recycle(starters[j]);                        }                        return startResult;                    }                    final ActivityRecord started = outActivity[0];                    if (started != null && started.getUid() == filterCallingUid) {                        // Only the started activity which has the same uid as the source caller                        // can be the caller of next activity.                        resultTo = started.token;                    } else {                        resultTo = sourceResultTo;                        // Different apps not adjacent to the caller are forced to be new task.                        if (i < starters.length - 1) {                            starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                        }                    }                }            } finally {                mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow(options != null ? options.getOriginalOptions() : null);                mService.continueWindowLayout();            }        }    } finally {        Binder.restoreCallingIdentity(origId);    }    return START_SUCCESS;}

在下面办法中通过对ActivityStarter数组循环执行启动activity申请,execute()最终调用该类int execute()办法,后续调用流程就跟startHomeActivity()统一,具体阐明参见上一篇博文中
7.AMS.systemReady办法以及后续章节源码阐明

4.利用内启动startActivity()

以Activity.startActivity()为例,

//启动activitypublic void startActivity(Intent intent, @Nullable Bundle options) {    if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN) && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {        if (TextUtils.equals(getPackageName(), intent.resolveActivity(getPackageManager()).getPackageName())) {            // Apply Autofill restore mechanism on the started activity by startActivity()            final IBinder token = mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);            // Remove restore ability from current activity            mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);            mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);            // Put restore token            intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);            intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);        }    }    if (options != null) {        startActivityForResult(intent, -1, options);    } else {        // Note we want to go through this call for compatibility with        // applications that may have overridden the method.        startActivityForResult(intent, -1);    }}//startActivityForResultpublic void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {    if (mParent == null) {        options = transferSpringboardActivityOptions(options);        //Instrumentation.execStartActivity        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);        ...        ...    } else {        ...        ...    }}//Instrumentation.execStartActivitypublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {    ...    //参数及监控相干解决    ...    try {        ...        //此处getService 返回IActivityTaskManager抽象类,理论被ActivityTaskManagerService实现        int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), who.getAttributionTag(), 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;}//ActivityTaskManagerService.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) {    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId());}//startActivityAsUserprivate 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) {    ...    ...    //此处getActivityStartController()返回ActivityStartController对象,调用obtainStarter理论调用ActivityStarter,通过execute()执行启动申请    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();}//调用execute()最终执行executeRequest()启动,源码门路:/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
  • execute()办法解决Activity启动申请,进入到
  • executeRequest(mRequest);执行执行一系列权限查看,进入到
  • startActivityUnchecked()校验初步权限查看是否实现,进入到
  • startActivityInner()启动 Activity,并确定是否将activity增加到栈顶,进入到
  • startActivityLocked()判断以后activity是否可见以及是否须要为其新建Task,并将ActivityRecord退出到Task栈顶中,进入到
  • resumeFocusedTasksTopActivities() - RootWindowContainer.java ,次要判断targetRootTask是否处于栈顶,同时判断task是否处于暂停状态,进入到
  • resumeTopActivityUncheckedLocked() - Task.java,递归调用该办法并查找栈顶可显示activity以及状态是否暂停,进入到
  • resumeTopActivityInnerLocked() - Task.java,该办法次要解决ActivityRecord、设置resume状态、筹备启动activity,进入到
  • resumeTopActivity() - TaskFragment.java,查找栈顶activity是否处于running,查看所有暂停操作是否实现,进入到
  • startSpecificActivity() - ActivityTaskSupervisor.java,如果activity已运行则间接启动,未运行则启动指标Activity,开启启动新过程,进入到
  • realStartActivityLocked() - ActivityTaskManagerService.java,因为Activity.startActivity()在调用前过程已创立,所以分支走到这里

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {  ...  try {      ...      try {          ...          //创立activity启动事务          final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);          //判断activity是否是前向转换,即从一个Activity转换到另一个Activity,后者在工作栈中的地位比前者更靠前          final boolean isTransitionForward = r.isTransitionForward();          //获取IBinder对象          final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();          //将蕴含activity回调(蕴含生命周期申请/回调)增加到音讯汇合开端          clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), 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.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor, proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), results, newIntents, r.takeOptions(), isTransitionForward, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));          //设置生命周期状态申请          final ActivityLifecycleItem lifecycleItem;          if (andResume) {              lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);          } else {              lifecycleItem = PauseActivityItem.obtain();          }          clientTransaction.setLifecycleStateRequest(lifecycleItem);          //获取ClientLifecycleManager对象,执行事务          mService.getLifecycleManager().scheduleTransaction(clientTransaction);      }      ...  }  ...}

    ClientLifecycleManager.scheduleTransaction()最终调用ClientTransaction.java中的shedule()办法

该办法将客户端事务退出到零碎事务队列中,并按程序执行preExecute实现前置工作,发送事务message,调用TransactionExecutor.execute()执行所有回调及生命周期转换

mClient对象为IApplicationThread,这是aidl接口,其理论执行对象为ActivityThread,继承于ClientTransactionHandler,外部也实例化TransactionExecutor对象,

public void schedule() throws RemoteException {    mClient.scheduleTransaction(this);}//最终调用ActivityThread.scheduleTransaction(),重写了父类ClientTransactionHandler.scheduleTransaction(),执行transaction操作@Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {    ActivityThread.this.scheduleTransaction(transaction);}void scheduleTransaction(ClientTransaction transaction) {    transaction.preExecute(this);    //发送handle message    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}

咱们接着看下ActivityThread handleMessage() - case EXECUTE_TRANSACTION

case EXECUTE_TRANSACTION:    //获取message    final ClientTransaction transaction = (ClientTransaction) msg.obj;    //执行    mTransactionExecutor.execute(transaction);    if (isSystem()) {        //零碎过程內的事务在客户端回收掉        transaction.recycle();    }    // TODO(lifecycler): Recycle locally scheduled transactions.    break;//TransactionExecutor.execute()public void execute(ClientTransaction transaction) {    ...    //循环执行回调申请    executeCallbacks(transaction);    //执行生命周期回调    executeLifecycleState(transaction);    ...}
  • executeLifecycleState()会调用cycleToPath()用于在状态之间转换客户端, 进入到
  • performLifecycleSequence() ,通过之前初始化的状态转换客户端,此时状态走到ON_CREATE,进入到
  • handleLaunchActivity() - ClientTransactionHandler.java,该类为抽象类,具体实现在ActivityThread中,
  • ActivityThread.handleLaunchActivity() ,筹备执行启动,进入到
  • performLaunchActivity() , 启动activity的外围实现办法,次要解决查看包信息,组件名称,Context,组装classLoader,调用mInstrumentation.newActivity()

    //启动activity外围实现办法private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {  ActivityInfo aInfo = r.activityInfo;  //校验包信息  if (r.packageInfo == null) {      r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);  }  //校验启动组件信息  ComponentName component = r.intent.getComponent();  if (component == null) {      component = r.intent.resolveActivity(mInitialApplication.getPackageManager());      r.intent.setComponent(component);  }  if (r.activityInfo.targetActivity != null) {      component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);  }  //创立context  ContextImpl appContext = createBaseContextForActivity(r);  Activity activity = null;  try {      //获取ClassLoader - /frameworks/base/core/java/android/app/ContextImpl.java      java.lang.ClassLoader cl = appContext.getClassLoader();      //实例化activity,反射生成      activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);      StrictMode.incrementExpectedActivityCount(activity.getClass());      r.intent.setExtrasClassLoader(cl);      r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo), appContext.getAttributionSource());      if (r.state != null) {          r.state.setClassLoader(cl);      }  } catch(Exception e) {      if (!mInstrumentation.onException(activity, e)) {          throw new RuntimeException("Unable to instantiate activity " + component + ": " + e.toString(), e);      }  }  try {      //获取Application,默认从缓存获取,不存在通过Instrumentation.newApplication()创立新的返回,同时回调Application.onCreate()      Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);      if (localLOGV) Slog.v(TAG, "Performing launch of " + r);      if (localLOGV) Slog.v(TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir());      // updatePendingActivityConfiguration() reads from mActivities to update      // ActivityClientRecord which runs in a different thread. Protect modifications to      // mActivities to avoid race.      synchronized(mResourcesManager) {          mActivities.put(r.token, r);      }      if (activity != null) {          CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());          Configuration config = new Configuration(mConfigurationController.getCompatConfiguration());          if (r.overrideConfig != null) {              config.updateFrom(r.overrideConfig);          }          if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config);          //设置Window          Window window = null;          if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {              window = r.mPendingRemoveWindow;              r.mPendingRemoveWindow = null;              r.mPendingRemoveWindowManager = null;          }          //初始化Activity resources          // Activity resources must be initialized with the same loaders as the          // application context.           appContext.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));          //设置以后context          appContext.setOuterContext(activity);          //调用activity attach办法          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.activityConfigCallback, r.assistToken, r.shareableActivityToken);          //设置activity intent          if (customIntent != null) {              activity.mIntent = customIntent;          }          r.lastNonConfigurationInstances = null;          //期待网络规定更新 - ActivityManagerService.waitForNetworkStateUpdate()          checkAndBlockForNetworkAccess();          activity.mStartedActivity = false;          //设置主题theme          int theme = r.activityInfo.getThemeResource();          if (theme != 0) {              activity.setTheme(theme);          }          if (r.mActivityOptions != null) {              activity.mPendingOptions = r.mActivityOptions;              r.mActivityOptions = null;          }          activity.mLaunchedFromBubble = r.mLaunchedFromBubble;          activity.mCalled = false;          // Assigning the activity to the record before calling onCreate() allows          // ActivityThread#getActivity() lookup for the callbacks triggered from          // ActivityLifecycleCallbacks#onActivityCreated() or          // ActivityLifecycleCallback#onActivityPostCreated().          r.activity = activity;          //开始回调activity.onCreate()          if (r.isPersistable()) {              mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);          } else {              mInstrumentation.callActivityOnCreate(activity, r.state);          }          if (!activity.mCalled) {              throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()");          }          mLastReportedWindowingMode.put(activity.getActivityToken(), config.windowConfiguration.getWindowingMode());      }      r.setState(ON_CREATE);  } catch(SuperNotCalledException e) {      throw e;  } catch(Exception e) {      if (!mInstrumentation.onException(activity, e)) {          throw new RuntimeException("Unable to start activity " + component + ": " + e.toString(), e);      }  }  //返回activity实例  return activity;}

    5.小结

    在startActivity()调用启动中,Instrumentation类表演非常重要的角色,该类中定义了一系列call办法,监控着activity生命周期办法以及application.onCreate()、execStartActivity()等,用来解决利用和零碎过程所有交互,在Android插件化相干解决中,也能够看到hook instrumentation相干操作,理解源码调用流程也能帮忙咱们找到适合的切入点

6.文档阐明

因为源码流程较长,整体调用链十分繁冗,可能存在错漏的中央,欢送在浏览时提出问题和有余

参考文档:

Android Code Search

/ - OpenGrok cross reference for / (aospxref.com)