相关文章 Android系统启动流程(1)  ——  解析init进程启动过程 Android系统启动流程(2)  ——  解析Zygote进程启动过程 Android系统启动流程(3)  ——  解析SystemServer进程启动过程        系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,也就是我们手机看到的桌面,这个应用程序就叫作 Launcher。Launcher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上, 这样用户可以通过点击这些快捷图标来启动相应的应用程序。        通俗来讲 Launcher 就是 Android 系统的桌面,它的作用主要有以下两点:        SystemServer 进程在启动的过程中会启动ActivityManagerServer、PackageManagerService服务, PackageManagerService启动之后会将系统中的应用程序安装完成。AMS(ActivityManagerServer) 会将 Launcher 启动起来。        启动Launcher的入口为AMS的sytemReady方法,它在SystemServer的startOtherServices方法中被调用,代码如下所示: frameworks/base/services/java/com/android/server/SystemServer.java          在Android8.0开始在源码中引入了Java Lambda表达式,接下来分析AMS的systemReady方法做了什么,代码如下:        Direct Boot模式下,仅限于运行一些关键的、紧急的APP,比如:        在Android 7.0以后,在启动Launcher之前会先启动一个FallbackHome;  FallbackHome是Settings里的一个activity,Settings的android:directBootAware为true,而且FallbackHome在category中配置了Home属性;而Launcher的android:directBootAware为false,所以在DirectBoot模式下,只有FallbackHome可以启动。即先启动com.android.tv.settings/.FallbackHome(或者是com.android.settings/.FallbackHome ) ,待用户解锁后再启动com.android.launcher3/.Launcher。想更深入了解Direct Boot模式和FallbackHome所做的工作的同学可以去阅读源码研究,这里就不做深入说明,下面我们继续Lancher的启动过程。        在注释1处调用 ActivityStackSupervisor 的resumeHomeStackTask 方法并且传入的reason参数就是”noMoreActivities“,代码如下所示:          可以看到intent-filter设置了<category android:name=”android.intent.category.HOME” /> 属性,这样名称为com.android.launcher3.Launcher的Activity 就成为了主 Activity。 从前面 AMS的startHomeActivityLocked方法的注释5处,我们知如 Launcher 没有启动就会调用ActivityStarter的startHomeActivityLocked 方法来启动Launcher ,如下所示: frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java         在注释1处将 Launcher放入HomeStack 中,HomeStack 是在 ActivityStackSupervisor 中定义的用于存储Launcher的变量 。接着调用注释2处的startActivityLocked方法来启动Launcher, 剩余的过程会和普通Activity 启动过程类似,后面会出Activity启动过程相关文章,这里就先不做讲解。最终进Launcher的onCreate 方注中,到这里 Launcher就启动完成了。        Launcher 完成启动后会做很多的工作,作为桌面它会显示应用程序图标, 这与应用程序开发有所关联,应用程序图标是用户进入应用程的入口,因此我们有必要了解 Launcher 是如何显示应用程序图标的。        在注释1处创建LoaderTask的对象mLoaderTask并将LoaderResult对象传入构造器,后面会用到这个LoaderResult的对象,在注释2处调用runOnWorkerThread方法,代码如下: packages/apps/Launcher3/src/com/android/launche3/LauncherModel.java        LoaderTask类实现了Runnable接口,当LoaderTask所描述的消息被处理时,则会调用它的run方法,LoaderTask的run方法代码如下所示: packages/apps/Launcher3/src/com/android/launche3/model/LoaderTask.java        在注释1处创建AppInfo信息并添加到mBgAllAppsList列表中。        在回到LoaderTask的run方法,在注释4处的mResult就是构造LoaderTask时传入的LoaderResult对象,调用LoaderResult的bindAllApps方法绑定App信息,代码如下: packages/apps/Launcher3/src/com/android/launche3/model/LoaderResult.java        在注释1处调用callbacks的bindAllApplications方法实质上就是调用Launcher的bindAllApplications方法,接下里分析Launcher中的bindAllApplications方法,代码如下:  packages/apps/Launcher3/src/com/android/launcher3/Launcher.javaLauncher启动过程
    1 Launcher 概述
    2 Launcher 启动过程介绍
 
 private void startOtherServices() {    mActivityManagerService.systemReady(() -> {             Slog.i(TAG, "Making services ready");             traceBeginAndSlog("StartActivityManagerReadyPhase");             mSystemServiceManager.startBootPhase(                     SystemService.PHASE_ACTIVITY_MANAGER_READY);              ...                     }, BOOT_TIMINGS_TRACE_LOG);  } 
  public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {         ...          synchronized (this) {                ...              startHomeActivityLocked(currentUserId, "systemReady"); // ... 1                         ...              mStackSupervisor.resumeFocusedStackTopActivityLocked();// ... 2             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);         }     }    特别注意!!!
 
    boolean startHomeActivityLocked(int userId, String reason) {                  Slog.wtf("ActivityManagerService", "reason = " + reason +                 " ;  mFactoryTest =" + mFactoryTest                 + " ; mTopAction = " + mTopAction                 + " ; userId = " + userId); // ...  1          if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL                 && mTopAction == null) {             // We are running in factory test mode, but unable to find             // the factory test app, so just sit around displaying the             // error message and don't try to start anything.             return false;         }         Intent intent = getHomeIntent();         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);         Slog.wtf("ActivityManagerService", "reason = " + reason                 + " ; aInfo = " + aInfo); // ... 2         if (aInfo != null) {             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));             Slog.wtf("ActivityManagerService", "reason = " + reason                     + " ; aInfo.applicationInfo.packageName = " + aInfo.applicationInfo.packageName); // ... 3             // Don't do this if the home app is currently being             // instrumented.             aInfo = new ActivityInfo(aInfo);             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);             ProcessRecord app = getProcessRecordLocked(aInfo.processName,                     aInfo.applicationInfo.uid, true);             if (app == null || app.instrumentationClass == null) {                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);             }         } else {             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());         }          return true;     }
        在AMS的systemReady方法中,注释1处调用startHomeActivityLocked方法是传入的reason参数的值是“systemReady”,在Log日志中我们发现reason为“systemReady”时,所启动的并不是我们的Launcher程序,而是Settings程序的FallbackHome这Activity。注释2处代码通过一系列调用之后最终调用到startHomeActivityLocked方法是传入的reason参数的值是“noMoreActivities resumeHomeStackTask” (这个值我们后面具体分析是怎么传入的)时,在Log日志中我们发现reason为“noMoreActivities resumeHomeStackTask”时,所启动的才是我们的Launcher程序。
 
    boolean resumeFocusedStackTopActivityLocked() {         return resumeFocusedStackTopActivityLocked(null, null, null);     }      boolean resumeFocusedStackTopActivityLocked(             ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {          if (!readyToResume()) {             return false;         }          if (targetStack != null && isFocusedStack(targetStack)) {             return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); // ... 1         }          final ActivityRecord r = mFocusedStack.topRunningActivityLocked();         if (r == null || r.state != RESUMED) {             mFocusedStack.resumeTopActivityUncheckedLocked(null, null);         } else if (r.state == RESUMED) {             // Kick off any lingering app transitions form the MoveTaskToFront operation.             mFocusedStack.executeAppTransition(targetOptions);         }          return false;     } 
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {         if (mStackSupervisor.inResumeTopActivity) {             // Don't even start recursing.             return false;         }          boolean result = false;         try {             // Protect against recursion.             mStackSupervisor.inResumeTopActivity = true;             result = resumeTopActivityInnerLocked(prev, options); // ... 1         } finally {             mStackSupervisor.inResumeTopActivity = false;         }          // 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 = topRunningActivityLocked(true /* focusableOnly */);         if (next == null || !next.canTurnScreenOn()) {             checkReadyForSleep();         }          return result;     }  
     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {                 ...         if (!hasRunningActivity) {             // There are no activities left in the stack, let's look somewhere else.             return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");  // ... 1         }                       ...     }  
    private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,             ActivityOptions options, String reason) {                  ...         return isOnHomeDisplay() &&                 mStackSupervisor.resumeHomeStackTask(prev, reason); // ... 1     } 
     boolean resumeHomeStackTask(ActivityRecord prev, String reason) {                   ...          // reason 的值为noMoreActivities         final String myReason = reason + " resumeHomeStackTask"; // ... 1          // Only resume home activity if isn't finishing.         if (r != null && !r.finishing) {             moveFocusableActivityStackToFrontLocked(r, myReason);             return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);         }         return mService.startHomeActivityLocked(mCurrentUser, myReason); // ... 2     }  
    boolean startHomeActivityLocked(int userId, String reason) {         // 判断工厂模式和mTopAction的值         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL                 && mTopAction == null) { // ... 1             // We are running in factory test mode, but unable to find             // the factory test app, so just sit around displaying the             // error message and don't try to start anything.             return false;         }          // 创建Launcher启动所需的Intent         Intent intent = getHomeIntent(); // ... 2         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); // ... 3         if (aInfo != null) {             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));             // Don't do this if the home app is currently being             // instrumented.             aInfo = new ActivityInfo(aInfo);             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);             ProcessRecord app = getProcessRecordLocked(aInfo.processName,                     aInfo.applicationInfo.uid, true);             if (app == null || app.instr == null) { // ... 4                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);                 // For ANR debugging to verify if the user activity is the one that actually                 // launched.                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); // ... 5             }         } else {             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());         }          return true;     } 
    Intent getHomeIntent() {         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);         intent.setComponent(mTopComponent);         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {             intent.addCategory(Intent.CATEGORY_HOME);         }         return intent;     } 
    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {         ActivityInfo ai = null;         ComponentName comp = intent.getComponent();         try {             if (comp != null) {                 // Factory test.                              ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);             } else {                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(                         intent,                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),                         flags, userId);                  if (info != null) {                     ai = info.activityInfo;                 }             }         } catch (RemoteException e) {             // ignore         }          return ai;     } 
<manifest     xmlns:android="https://schemas.android.com/apk/res/android"     package="com.android.launcher3">     <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>     ...      <application         android:backupAgent="com.android.launcher3.LauncherBackupAgent"         android:fullBackupOnly="true"         android:fullBackupContent="@xml/backupscheme"         android:hardwareAccelerated="true"         android:icon="@drawable/ic_launcher_home"         android:label="@string/derived_app_name"         android:theme="@style/LauncherTheme"         android:largeHeap="@bool/config_largeHeap"         android:restoreAnyVersion="true"         android:supportsRtl="true" >          <!--         Main launcher activity. When extending only change the name, and keep all the         attributes and intent filters the same         -->         <activity             android:name="com.android.launcher3.Launcher"             android:launchMode="singleTask"             android:clearTaskOnLaunch="true"             android:stateNotNeeded="true"             android:windowSoftInputMode="adjustPan"             android:screenOrientation="nosensor"             android:configChanges="keyboard|keyboardHidden|navigation"             android:resizeableActivity="true"             android:resumeWhilePausing="true"             android:taskAffinity=""             android:enabled="true">             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                 <category android:name="android.intent.category.HOME" />                 <category android:name="android.intent.category.DEFAULT" />                 <category android:name="android.intent.category.MONKEY"/>                 <category android:name="android.intent.category.LAUNCHER_APP" />             </intent-filter>         </activity>              ...      </application> </manifest>  
    void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {         // 将Launcher放入HomeStack中         mSupervisor.moveHomeStackTaskToTop(reason); // ... 1         mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,                 null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,                 null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,                 null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,                 null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,                 0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,                 false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,                 null /*inTask*/, "startHomeActivity: " + reason); // ... 2         if (mSupervisor.inResumeTopActivity) {             // If we are in resume section already, home activity will be initialized, but not             // resumed (to avoid recursive resume) and will stay that way until something pokes it             // again. We need to schedule another resume.             mSupervisor.scheduleResumeTopActivities();         }     }    3 Launcher 中应用图标显示过程
 
  @Override     protected void onCreate(Bundle savedInstanceState) {                 ...                 LauncherAppState app = LauncherAppState.getInstance(this); // ... 1          // Load configuration-specific DeviceProfile         mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);         if (isInMultiWindowModeCompat()) {             Display display = getWindowManager().getDefaultDisplay();             Point mwSize = new Point();             display.getSize(mwSize);             mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);         }          mOrientation = getResources().getConfiguration().orientation;         mSharedPrefs = Utilities.getPrefs(this);         mIsSafeModeEnabled = getPackageManager().isSafeMode();          mModel = app.setLauncher(this); // ...2          ...          if (!mModel.startLoader(currentScreen)) { // ... 3              // If we are not binding synchronously, show a fade in animation when             // the first page bind completes.             mDragLayer.setAlpha(0);         } else {             // Pages bound synchronously.             mWorkspace.setCurrentPage(currentScreen);              setWorkspaceLoading(true);         }          ...      }    
    LauncherModel setLauncher(Launcher launcher) {         getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);         mModel.initialize(launcher); // ... 1         return mModel;     }  
    public void initialize(Callbacks callbacks) {         synchronized (mLock) {             Preconditions.assertUIThread();             mCallbacks = new WeakReference<>(callbacks);         }     } 
    ...         // 创建了具有消息循环的线程HandlerThread对象     @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); // ... 1     static {         sWorkerThread.start();     }     @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper()); // ... 2       ...       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(new Runnable() {                             public void run() {                                 oldCallbacks.clearPendingBinds();                             }                         });                  // If there is already one running, tell it to stop.                 stopLoader();                 LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,                         mBgAllAppsList, synchronousBindPage, mCallbacks);  // ... 3                 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); // ... 4                 }             }         }         return false;     } 
    public void startLoaderForResults(LoaderResults results) {         synchronized (mLock) {             stopLoader();             mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results); // ... 1             runOnWorkerThread(mLoaderTask); // ... 2         }     } 
    private static void runOnWorkerThread(Runnable r) {         if (sWorkerThread.getThreadId() == Process.myTid()) {             r.run(); // 如果当前线程是工作线程,直接执行run方法         } else {             // If we are not on the worker thread, then post to the worker handler             // 如果当前线程不是工作现在,那么post到工作线程处理。             sWorker.post(r);          }     } 
    public void run() {         synchronized (this) {             // Skip fast if we are already stopped.             if (mStopped) {                 return;             }         }          try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {             long now = 0;             if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");             // 加载工作区信息             loadWorkspace(); // ... 1              verifyNotStopped();             if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");              // 绑定工作区信息             mResults.bindWorkspace(); // ... 2              // Take a break             if (DEBUG_LOADERS) {                 Log.d(TAG, "step 1 completed, wait for idle");                 now = SystemClock.uptimeMillis();             }             waitForIdle();             if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");             verifyNotStopped();              // second step             if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");              // 加载系统已经安装的应用程序信息             loadAllApps(); // ... 3              if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps");             verifyNotStopped();              // 绑定Appinfo             mResults.bindAllApps(); // ... 4                          ...          } catch (CancellationException e) {             // Loader stopped, ignore             if (DEBUG_LOADERS) {                 Log.d(TAG, "Loader cancelled", e);             }         }     } 
    private void loadAllApps() {                 ...          // Clear the list of apps         mBgAllAppsList.clear();         for (UserHandle user : profiles) {                          ...              final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);             ...                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); // ... 1             }              ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user);         }          ...      } 
 public void bindAllApps() {         // shallow copy         // 将mBgAllAppList中的data属性克隆一份         @SuppressWarnings("unchecked")         final ArrayList<AppInfo> list = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();          Runnable r = new Runnable() {             public void run() {                 Callbacks callbacks = mCallbacks.get();                 if (callbacks != null) {                     // 这里的callbacks就是Launcher的对象                     callbacks.bindAllApplications(list); // ... 1                 }             }         };         mUiExecutor.execute(r);     } 
 public void bindAllApplications(final ArrayList<AppInfo> apps) {          ...          if (mAppsView != null) {             Executor pendingExecutor = getPendingExecutor();             if (pendingExecutor != null && mState != State.APPS) {                 // Wait until the fade in animation has finished before setting all apps list.                 pendingExecutor.execute(r);                 return;             }              mAppsView.setApps(apps); // ... 1         }                 ...     } 
    public void setApps(List<AppInfo> apps) {         mApps.setApps(apps);     } 
    @Override     protected void onFinishInflate() {         super.onFinishInflate();                 ...          mAppsRecyclerView = findViewById(R.id.apps_list_view); // ... 1         mAppsRecyclerView.setApps(mApps); // ... 2         mAppsRecyclerView.setLayoutManager(mLayoutManager);         mAppsRecyclerView.setAdapter(mAdapter); //  ... 3                 ...     }  
 Android 系统启动流程
     1.启动电源以及系统启动 
     2. 引导程序 Bootloader 
     3. Linux 内核启动 
     4. init 进程启动 
     5. Zygote 进程启动 
     6. System Server 进程启动 
     7. Launcher 启动 
 
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)