android lancher 目录,【 Android 10 系统启动 】系列 -- Launcher(应用门户)

前言

由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 《 Thinking in Android 》 来阅读这边文章,希望这篇文章能帮你梳理清楚 “Launcher 启动流程”。

核心源码

关键类

路径

SystemServer.java

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

ActivityManagerService.java

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

ActivityStack.java

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

ActivityTaskManagerService.java

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

RootActivityContainer.java

frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

Launcher.java

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

LauncherModel.java

packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

LauncherAppState.java

packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java

LoaderTask.java

packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java

一、Launcher 启动流程

Android 系统启动的最后一步是启动一个 Home 应用程序,这个应用程序用来显示系统中已经安装的应用程序,我们称呼这个应用程序为 Launcher。

应用程序 Launcher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序的信息,并将这些信息封装成一个 快捷图标 列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序了。

1.1 SystemServer.startOtherServices()

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

public final class SystemServer {

private ActivityManagerService mActivityManagerService;

private void startOtherServices() {

... ...

mActivityManagerService.systemReady(() -> { // 调用 ActivityManagerService 的 systemReady() 方法

Slog.i(TAG, "Making services ready");

... ...

}

... ...

}

}

在 startOtherServices() 方法中,会调用 ActivityManagerService 的 systemReady() 方法。

1.2 ActivityManagerService.systemReady()

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

public class ActivityManagerService extends IActivityManager.Stub

implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

@VisibleForTesting

public ActivityTaskManagerInternal mAtmInternal;

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {

... ...

synchronized (this) {

... ...

// 调用 resumeTopActivities() 方法,这是一个抽象方法

mAtmInternal.resumeTopActivities(false /* scheduleIdle */);

mUserController.sendUserSwitchBroadcasts(-1, currentUserId);

... ...

}

... ...

}

}

1.3 ActivityTaskManagerService.resumeTopActivities()

resumeTopActivities() 方法由 ActivityTaskManagerService 的内部类 LocalService 实现。

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

RootActivityContainer mRootActivityContainer;

final class LocalService extends ActivityTaskManagerInternal {

... ...

@Override

public void resumeTopActivities(boolean scheduleIdle) {

synchronized (mGlobalLock) {

// 调用 RootActivityContainer 的 resumeFocusedStacksTopActivities() 方法

mRootActivityContainer.resumeFocusedStacksTopActivities();

if (scheduleIdle) {

mStackSupervisor.scheduleIdleLocked();

}

}

}

... ...

}

}

1.4 RootActivityContainer.resumeFocusedStacksTopActivities()

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

class RootActivityContainer extends ConfigurationContainer

implements DisplayManager.DisplayListener {

boolean resumeFocusedStacksTopActivities() {

return resumeFocusedStacksTopActivities(null, null, null);

}

boolean resumeFocusedStacksTopActivities(

ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

... ...

for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {

boolean resumedOnDisplay = false;

final ActivityDisplay display = mActivityDisplays.get(displayNdx);

... ...

if (!resumedOnDisplay) {

final ActivityStack focusedStack = display.getFocusedStack();

if (focusedStack != null) {

// 调用 resumeTopActivityUncheckedLocked() 方法

focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);

}

}

}

return result;

}

}

1.5 ActivityStack.resumeTopActivityUncheckedLocked()

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

class ActivityStack extends ConfigurationContainer {

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); // 调用 resumeTopActivityInnerLocked() 方法

final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

if (next == null || !next.canTurnScreenOn()) {

checkReadyForSleep();

}

} finally {

mInResumeTopActivity = false;

}

return result;

}

}

1.6 ActivityStack.resumeTopActivityInnerLocked()

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

class ActivityStack extends ConfigurationContainer {

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

... ...

if (!hasRunningActivity) {

// There are no activities left in the stack, let's look somewhere else.

return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);

}

... ...

}

}

1.7 ActivityStack.resumeNextFocusableActivityWhenStackIsEmpty()

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

class ActivityStack extends ConfigurationContainer {

protected final RootActivityContainer mRootActivityContainer;

private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,

ActivityOptions options) {

final String reason = "noMoreActivities";

if (!isActivityTypeHome()) {

final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);

if (nextFocusedStack != null) {

return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,

prev, null /* targetOptions */);

}

}

// If the current stack is a home stack, or if focus didn't switch to a different stack -

// just start up the Launcher...

ActivityOptions.abort(options);

if (DEBUG_STATES) Slog.d(TAG_STATES,

"resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");

// 调用 resumeHomeActivity() 方法

return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);

}

}

1.8 RootActivityContainer.resumeHomeActivity()

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

class RootActivityContainer extends ConfigurationContainer

implements DisplayManager.DisplayListener {

boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {

if (!mService.isBooting() && !mService.isBooted()) {

// Not ready yet!

return false;

}

if (displayId == INVALID_DISPLAY) {

displayId = DEFAULT_DISPLAY;

}

final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();

final String myReason = reason + " resumeHomeActivity";

// Only resume home activity if isn't finishing.

if (r != null && !r.finishing) {

r.moveFocusableActivityToTop(myReason);

return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null);

}

// 调用 startHomeOnDisplay() 方法

return startHomeOnDisplay(mCurrentUser, myReason, displayId);

}

}

1.9 RootActivityContainer.startHomeOnDisplay()

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

class RootActivityContainer extends ConfigurationContainer

implements DisplayManager.DisplayListener {

ActivityTaskManagerService mService;

boolean startHomeOnDisplay(int userId, String reason, int displayId) {

return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,

false /* fromHomeKey */);

}

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,

boolean fromHomeKey) {

... ...

// Updates the home component of the intent.

homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));

homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);

... ...

// 启动 Launcher

mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,

displayId);

return true;

}

}

二、应用图标显示流程

接下来我们看看 Launcher 是如何加载并显示所有已安装 Apk 的:

2.1 Launcher.onCreate()

// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

/**

* Default launcher application.

*/

public class Launcher extends BaseDraggingActivity implements LauncherExterns,

LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate,

InvariantDeviceProfile.OnIDPChangeListener {

@Override

protected void onCreate(Bundle savedInstanceState) {

... ...

LauncherAppState app = LauncherAppState.getInstance(this);

... ...

mModel = app.setLauncher(this); // 调用 setLauncher() 方法

... ...

if (!mModel.startLoader(currentScreen)) { // 见 2.4

if (!internalStateHandled) {

// If we are not binding synchronously, show a fade in animation when

// the first page bind completes.

mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);

}

} else {

// Pages bound synchronously.

mWorkspace.setCurrentPage(currentScreen);

setWorkspaceLoading(true);

}

... ...

}

}

2.2 LauncherAppState.setLauncher()

// packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java

public class LauncherAppState {

LauncherModel setLauncher(Launcher launcher) {

getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);

mModel.initialize(launcher); // 调用 initialize() 方法

return mModel;

}

}

2.3 LauncherModel.initialize()

// packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

public class LauncherModel extends BroadcastReceiver

implements LauncherAppsCompat.OnAppsChangedCallbackCompat {

/**

* Set this as the current Launcher activity object for the loader.

*/

public void initialize(Callbacks callbacks) {

synchronized (mLock) {

Preconditions.assertUIThread();

mCallbacks = new WeakReference<>(callbacks);

}

}

}

在 initialize 方法中会将 Callbacks(也就是传入的 Launcher)封装成一个 弱引用对象,因此我们得知 mCallbacks 变量指的就是封装成弱引用对象的 Launcher。

重新回到 oncreate() 函数,有个 startLoader() 方法!

2.4 LauncherModel.startLoader()

// packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

public class LauncherModel extends BroadcastReceiver

implements LauncherAppsCompat.OnAppsChangedCallbackCompat {

public boolean startLoader(int synchronousBindPage) {

// Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems

InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);

synchronized (mLock) {

// Don't bother to start the thread if we know it's not going to do anything

if (mCallbacks != null && mCallbacks.get() != null) {

final Callbacks oldCallbacks = mCallbacks.get();

// Clear any pending bind-runnables from the synchronized load process.

mUiExecutor.execute(oldCallbacks::clearPendingBinds);

// If there is already one running, tell it to stop.

stopLoader();

LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,

mBgAllAppsList, synchronousBindPage, mCallbacks);

if (mModelLoaded && !mIsLoaderTaskRunning) {

// 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();

// 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 {

startLoaderForResults(loaderResults); // 调用 startLoaderForResults() 方法

}

}

}

return false;

}

}

2.5 LauncherModel.startLoaderForResults()

// packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

public class LauncherModel extends BroadcastReceiver

implements LauncherAppsCompat.OnAppsChangedCallbackCompat {

@Thunk static final Handler sWorker = new Handler(mWorkerLooper);

public void startLoaderForResults(LoaderResults results) {

synchronized (mLock) {

stopLoader();

mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);

// Always post the loader task, instead of running directly (even on same thread) so

// that we exit any nested synchronized blocks

sWorker.post(mLoaderTask);

}

}

}

2.6 LoaderTask.run()

当 LoaderTask 所描述的消息被处理时则会调用它的 run() 方法:

// packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java

public class LoaderTask implements Runnable {

public void run() {

synchronized (this) {

// Skip fast if we are already stopped.

if (mStopped) {

return;

}

}

try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {

TraceHelper.partitionSection(TAG, "step 1.1: loading workspace");

loadWorkspace(); // 加载工作区信息

verifyNotStopped();

TraceHelper.partitionSection(TAG, "step 1.2: bind workspace workspace");

mResults.bindWorkspace();

... ...

// second step

TraceHelper.partitionSection(TAG, "step 2.1: loading all apps");

List allActivityList = loadAllApps(); // 加载系统已经安装的应用程序信息

TraceHelper.partitionSection(TAG, "step 2.2: Binding all apps");

verifyNotStopped();

mResults.bindAllApps();

... ...

// third step

TraceHelper.partitionSection(TAG, "step 3.1: loading deep shortcuts");

loadDeepShortcuts();

verifyNotStopped();

TraceHelper.partitionSection(TAG, "step 3.2: bind deep shortcuts");

mResults.bindDeepShortcuts();

... ...

// fourth step

TraceHelper.partitionSection(TAG, "step 4.1: loading widgets");

List allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null);

verifyNotStopped();

TraceHelper.partitionSection(TAG, "step 4.2: Binding widgets");

mResults.bindWidgets();

... ...

transaction.commit();

} catch (CancellationException e) {

// Loader stopped, ignore

TraceHelper.partitionSection(TAG, "Cancelled");

}

TraceHelper.endSection(TAG);

}

}

2.7 LoaderTask.loadAllApps()

// packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java

public class LoaderTask implements Runnable {

private List loadAllApps() {

final List profiles = mUserManager.getUserProfiles();

List allActivityList = new ArrayList<>();

// Clear the list of apps

mBgAllAppsList.clear();

for (UserHandle user : profiles) {

// Query for the set of apps

final List apps = mLauncherApps.getActivityList(null, user);

// Fail if we don't have any apps

// TODO: Fix this. Only fail for the current user.

if (apps == null || apps.isEmpty()) {

return allActivityList;

}

boolean quietMode = mUserManager.isQuietModeEnabled(user);

// Create the ApplicationInfos

for (int i = 0; i < apps.size(); i++) {

LauncherActivityInfo app = apps.get(i);

// This builds the icon bitmaps.

mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);

}

allActivityList.addAll(apps);

}

if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {

// get all active sessions and add them to the all apps list

for (PackageInstaller.SessionInfo info :

mPackageInstaller.getAllVerifiedSessions()) {

mBgAllAppsList.addPromiseApp(mApp.getContext(),

PackageInstallerCompat.PackageInstallInfo.fromInstallingState(info));

}

}

mBgAllAppsList.added = new ArrayList<>();

return allActivityList;

}

}

自此,Launcher 的启动和应用加载的流程源码分析完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值