成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Launcher進程的啟動到用戶界面的呈現,揭示每個階段的關鍵步驟

移動開發 Android
隨著Android系統的不斷發展和更新,Launcher進程的啟動流程也可能會發生相應的變化和優化。Android系統還支持多種啟動Launcher的方式,如開機后自動啟動、短按Home鍵啟動以及異常崩潰后自動重啟等。

Launcher啟動器

Launcher(啟動器、桌面) 是 Android 操作系統上用于展示應用圖標、搜索應用、管理桌面快捷方式以及執行其他與設備主屏幕相關任務的用戶界面。設備的主屏幕布局和外觀是用戶與設備交互的主要方式。

Launcher特點:

  1. 「自定義性」:大多數 Launcher 都允許用戶自定義圖標、壁紙、桌面布局等。
  2. 「性能」:高效的 Launcher 可以提高設備的整體性能,因為它需要快速響應觸摸輸入并加載圖標和布局。
  3. 「兼容性」:隨著 Android 版本的更新,Launcher 需要確保與最新版本的 Android 兼容。
  4. 「安全性」:Launcher 必須確保用戶數據的安全,并防止惡意軟件的攻擊。
  5. 「多樣性」:市場上有許多不同的 Launcher 應用,每個應用都有其獨特的功能和界面設計。

Launcher進程啟動流程

  1. 「SystemServer進程啟動」:

SystemServer是Android系統中的一個核心進程,負責啟動和初始化各種系統服務。

在SystemServer的啟動過程中,會調用其他服務,如PackageManagerService(PMS)和ActivityManagerService(AMS)的初始化方法。

public final class SystemServer {
    private void run() {
    ...
    startBootstrapServices();
    startOtherServices();
    ...
  }
  
  private void startBootstrapServices() {
    ...
    mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    ...
  }
  
  private void startOtherServices() {
    ...
    mActivityManagerService.systemReady(() -> { 
      
    }, BOOT_TIMINGS_TRACE_LOG);
  }
}

在SystemServer啟動的時候,執行startOtherServices()方法中調用了AMS的systemReady()方法,通過該方法來啟動Launcher。

// Tag for timing measurement of main thread.
private static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
private static final TimingsTraceLog BOOT_TIMINGS_TRACE_LOG
            = new TimingsTraceLog(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);

private void startOtherServices() {
  ...
  mActivityManagerService.systemReady(() -> {
    Slog.i(TAG, "Making services ready");
    traceBeginAndSlog("StartActivityManagerReadyPhase");
    mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
    ...
  }, BOOT_TIMINGS_TRACE_LOG);
}
  1. 「PMS服務初始化」:

PMS服務會完成系統中應用程序的安裝和管理工作。

PMS會掃描/data/app目錄,加載已經安裝的應用程序信息。

  1. 「AMS服務初始化」:

AMS是Android系統中負責管理應用程序生命周期和活動(Activity)狀態的服務。

在AMS的初始化過程中,會注冊各種系統廣播接收器,包括與Launcher啟動相關的廣播。

4.「Launcher應用程序的注冊」:

Launcher應用程序是一個特殊的系統應用,它在AndroidManifest.xml文件中配置了特定的Intent Filter,以便系統能夠識別并啟動它。

通常,Launcher應用程序的Action被設置為Intent.ACTION_MAIN,而Category被設置為Intent.CATEGORY_HOME。

5.「SystemReady階段」:

當系統完成初始化并準備好啟動桌面時,AMS會調用其systemReady()方法。

在systemReady()方法中,AMS會檢查系統是否準備好啟動Launcher,并調用相關方法來啟動。

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
  ...
  synchronized (this) {
    ...
    startHomeActivityLocked(currentUserId, "systemReady");
    ...
  }
  ...
}

在startHomeActivityLocked()方法中,通過getHomeIntent()方法獲取到要啟動的HomeActivity的intent對象,mTopAction默認為INTENT.ACTION_MAIN,并添加CATEGORY_HOME的category標志。通過PackageManager去獲取對應符合的Activity,獲取對應的ActivityInfo,并獲取對應的進程記錄,此時對應的進程還沒啟動,為intent添加FLAG_ACTIVITY_NEW_TASK啟動參數開啟新棧,隨后調用ActivityStartController類的startHomeActivity()方法去執行啟動。

boolean startHomeActivityLocked(int userId, String reason) {
  ...
  Intent intent = getHomeIntent(); 
  ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
  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) {
      intent.setFlags(intent.getFlags() | 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;
      mActivityStartController.startHomeActivity(intent, aInfo, myReason);
    }
  }
  ...
  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;
}
  1. 「啟動Launcher進程」:

AMS啟動Launcher進程。

該方法會創建一個新的進程(如果Launcher尚未運行)來啟動Launcher應用程序。

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
  mSupervisor.moveHomeStackTaskToTop(reason);
  mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
    .setOutActivity(tmpOutRecord)
    .setCallingUid(0)
    .setActivityInfo(aInfo)
    .execute();
  mLastHomeActivityStartRecord = tmpOutRecord[0];
  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();
  }
}

int execute() {
  try {
    // TODO(b/64750076): Look into passing request directly to these methods to allow
    // for transactional diffs and preprocessing.
    if (mRequest.mayWait) {
      return startActivityMayWait(mRequest.caller, mRequest.callingUid,  ...);
    } else {
      return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent, ...);
    }
  } finally {
    onExecutionComplete();
  }
}
  1. 「Launcher進程啟動后的操作」:

Launcher進程啟動后,會向PMS請求已安裝應用程序的信息,并將這些信息展示在桌面上。

用戶可以通過點擊桌面上的應用程序圖標來啟動相應的應用程序。

@TargetApi(23)
public InvariantDeviceProfile(Context context) {
  WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  Display display = wm.getDefaultDisplay();
  DisplayMetrics dm = new DisplayMetrics();
  display.getMetrics(dm);
  ...
  ArrayList<InvariantDeviceProfile> closestProfiles = findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles(context));
  ...
}

ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles(Context context) {
  ArrayList<InvariantDeviceProfile> profiles = new ArrayList<>();
  try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
    final int depth = parser.getDepth();
    int type;
    while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
      if ((type == XmlPullParser.START_TAG) && "profile".equals(parser.getName())) {
        TypedArray a = context.obtainStyledAttributes(Xml.asAttributeSet(parser), R.styleable.InvariantDeviceProfile);
        int numRows = a.getInt(R.styleable.InvariantDeviceProfile_numRows, 0);
        int numColumns = a.getInt(R.styleable.InvariantDeviceProfile_numColumns, 0);
        float iconSize = a.getFloat(R.styleable.InvariantDeviceProfile_iconSize, 0);
        profiles.add(new InvariantDeviceProfile(
          a.getString(R.styleable.InvariantDeviceProfile_name),
          a.getFloat(R.styleable.InvariantDeviceProfile_minWidthDps, 0),
          a.getFloat(R.styleable.InvariantDeviceProfile_minHeightDps, 0),
          numRows,
          numColumns,
          a.getInt(R.styleable.InvariantDeviceProfile_numFolderRows, numRows),
          a.getInt(R.styleable.InvariantDeviceProfile_numFolderColumns, numColumns),
          iconSize,
          a.getFloat(R.styleable.InvariantDeviceProfile_landscapeIconSize, iconSize),
          a.getFloat(R.styleable.InvariantDeviceProfile_iconTextSize, 0),
          a.getInt(R.styleable.InvariantDeviceProfile_numHotseatIcons, numColumns),
          a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0),
          a.getResourceId(R.styleable.InvariantDeviceProfile_demoModeLayoutId, 0)));
        a.recycle();
      }
    }
  } catch (IOException|XmlPullParserException e) {
    throw new RuntimeException(e);
  }
  return profiles;
}

InvariantDeviceProfile對象主要是存儲App的基本配置信息,例如App圖標的尺寸大小,文字大小,每個工作空間或文件夾能顯示多少App等。

在LauncherModel的startLoader()方法中,新建了一個LoaderResults對象,通過startLoaderForResults()方法創建出一個LoaderTask的Runnable任務。

public boolean startLoader(int synchronousBindPage) {
  ...
  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) {
      ...
      LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel, mBgAllAppsList, synchronousBindPage, mCallbacks);
      if (mModelLoaded && !mIsLoaderTaskRunning) {
        ...
        return true;
      } else {
        startLoaderForResults(loaderResults);
      }
    }
  }
  return false;
}

public void startLoaderForResults(LoaderResults results) {
  synchronized (mLock) {
    stopLoader();
    mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);
    runOnWorkerThread(mLoaderTask);
  }
}

private static void runOnWorkerThread(Runnable r) {
  if (sWorkerThread.getThreadId() == Process.myTid()) {
    r.run();
  } else {
    // If we are not on the worker thread, then post to the worker handler
    sWorker.post(r);
  }
}

在LoaderTask的run()方法中,加載手機已安裝的App的信息,查詢數據庫獲取已安裝的App的相關信息,加載Launcher布局,并將數據轉化為View,綁定到界面上,最終就可以看到桌面顯示的宮格列表的桌面圖標了。

public void run() {
  ...
  try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
    // 查詢數據庫整理App信息,轉化為View綁定到界面
    loadWorkspace();
    mResults.bindWorkspace();
    loadAllApps();
    mResults.bindAllApps();
    loadDeepShortcuts();
    mResults.bindDeepShortcuts();
    mBgDataModel.widgetsModel.update(mApp, null);
    mResults.bindWidgets();
    transaction.commit();
  } catch (CancellationException e) {
    // Loader stopped, ignore
    TraceHelper.partitionSection(TAG, "Cancelled");
  }
  TraceHelper.endSection(TAG);
}

隨著Android系統的不斷發展和更新,Launcher進程的啟動流程也可能會發生相應的變化和優化。Android系統還支持多種啟動Launcher的方式,如開機后自動啟動、短按Home鍵啟動以及異常崩潰后自動重啟等。這些啟動方式的實現流程也有所不同,但基本流程都與上述步驟相似。

責任編輯:武曉燕 來源: 沐雨花飛蝶
相關推薦

2014-04-10 09:21:22

Windows Ser

2018-09-07 10:14:58

2021-02-05 10:27:23

轉型計劃項目負責人CIO

2023-07-31 11:19:16

2021-11-24 14:46:06

云計算云遷移數據中心

2009-12-25 14:52:49

2023-02-15 14:09:57

云托管云退出策略

2023-12-21 11:59:29

2024-03-26 08:58:55

集成測試軟件開發Python

2019-06-12 14:34:42

云平臺云遷移云計算

2020-09-28 06:32:53

VDI測試清單虛擬化

2025-02-08 11:23:55

2025-03-06 11:45:10

2019-01-02 05:05:12

物聯網網絡物聯網IOT

2023-01-17 10:37:40

2023-09-21 16:01:26

數字化轉型數據管理

2020-03-09 22:10:46

工業物聯網IIoT人工智能

2022-12-22 14:47:50

數據治理數字化轉型

2022-07-21 14:37:12

云計算安全云架構

2012-03-20 14:03:23

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久操av在线| 国产高清久久久 | 人人爽日日躁夜夜躁尤物 | 国产中文字幕在线观看 | 午夜影院在线 | 午夜一区| 成年网站在线观看 | 精品国产一区二区国模嫣然 | 国产精品久久久久久久久免费软件 | 久久精品中文字幕 | 日本一本视频 | 在线观看国产视频 | 婷婷福利视频导航 | 亚洲一区二区中文字幕在线观看 | 亚洲成人免费观看 | 好姑娘影视在线观看高清 | 91成人免费观看 | 四虎影音| 人人鲁人人莫人人爱精品 | 亚洲vs天堂 | 在线日韩视频 | 999在线精品 | 欧美伦理一区 | 欧美精品乱码99久久影院 | 337p日本欧洲亚洲大胆 | 成人av免费 | 蜜桃精品噜噜噜成人av | 久综合 | 欧美福利影院 | 精品av| 国产一区二区麻豆 | 视频在线h | 国产精品日韩高清伦字幕搜索 | 欧美日韩亚洲一区 | 国产超碰人人爽人人做人人爱 | 国产精品一区二区三区免费观看 | 欧美精品一区二区三区视频 | 九热在线 | 国产视频精品在线观看 | 国产一级成人 | 久久久成人精品 |