Android應用程式安裝與Launcher啟動機制

來源:互聯網
上載者:User

標籤:

 

以下資料摘錄整理自老羅的Android之旅部落格,是對老羅的部落格關於Android底層原理的一個抽象的知識概括總結(如有錯誤歡迎指出)(侵刪):
http://blog.csdn.net/luoshengyang/article/details/8923485
http://blog.csdn.net/luoshengyang/article/details/12957169

整理by Doing

          Android系統在啟動的過程中,會啟動一個應用程式管理服務PackageManagerService,這個服務負責掃描系統中特定的目錄,找到裡面的應用程式檔案,即以Apk為尾碼的檔案,然後對這些檔案進解析(其實就是解析應用程式設定檔AndroidManifest.xml的過程,並從裡面得到得到應用程式的相關資訊,例如得到應用程式的組件Activity、Service、Broadcast Receiver和Content Provider等資訊),得到應用程式的相關資訊,完成應用程式的安裝過程。        通過ActivityManagerService這個服務,我們就可以在系統中正常地使用這些應用程式了。 
  • PackageManagerService負責安裝系統的應用程式:
  1.  Android系統在啟動的過程中,Zygote進程啟動SystemServer組件,SystemServer組件啟動PackageManagerService服務、ActivityManagerService服務等。
  2. PackageManagerService服務啟動過程:建立了一個PackageManagerService服務執行個體,把這個服務添加到ServiceManager中去(ServiceManager是Android系統Binder處理序間通訊機制的守護進程,負責管理系統中的Binder對象)。
  3. PackageManagerService類的建構函式中開始執行安裝應用程式的過程:調用scanDirLI函數來掃描行動裝置上的五個目錄中的Apk檔案( /system/framework、 /system/app、 /vendor/app、/data/app、 /data/app-private),對於目錄中的每一個檔案,如果是以Apk作為尾碼名,那麼就調用scanPackageLI函數來對它進行解析和安裝:
  4. 首先會為這個Apk檔案建立一個PackageParser執行個體,接著調用這個執行個體的parsePackage函數來對這個Apk檔案進行解析(這個函數最後還會調用另外一個版本的scanPackageLI函數把來解析後得到的應用程式資訊儲存在PackageManagerService中。見後):
  5. 每一個Apk檔案都是一個歸檔檔案,它裡麵包含了Android應用程式的設定檔AndroidManifest.xml,這裡主要就是要對這個設定檔解析就行了。從Apk歸檔檔案中得到這個設定檔後,就調用另一外版本的parsePackage函數對這個應用程式進行解析:對AndroidManifest.xml檔案中的各個標籤進行解析,如application標籤的解析,這是通過調用parseApplication函數來進行的。
  6. 解析完成後,一層層返回,調用另一個版本的scanPackageLI函數,把前面解析應用程式得到的package、provider、service、receiver和activity等資訊儲存在PackageManagerService服務中(儲存在mPackages、mActivities、mReceivers、mServices等成員變數(HashMap類型)中)
  
  •         這些應用程式只是相當於在PackageManagerService服務註冊好了,如果我們想要在Android案頭上看到這些應用程式,還需要有一個Home應用程式(Android系統預設的Home應用程式就是Launcher),負責從PackageManagerService服務中把這些安裝好的應用程式取出來,並以友好的方式在案頭上展現出來,例如以快捷表徵圖的形式:
  1. 系統中的應用程式安裝好了以後,SystemServer組件接下來通過ActivityManagerService來啟動Home應用程式Launcher
  2. ActivityManagerService.startHomeActivityLocked() 建立一個CATEGORY_HOME類型的Intent,然後通過Intent.resolveActivityInfo函數向PackageManagerService查詢Category類型為HOME的Activity
  3. 由於是第一次啟動這個Activity,接下來調用函數getProcessRecordLocked返回來的ProcessRecord值為null,於是調用mMainStack.startActivityLocked函數啟動com.android.launcher2.Launcher這個Activity,接著調用它的onCreate函數。
  4. 把載入應用程式的操作為一個訊息來處理:sWorker(Handler)通過它的post方式把一個訊息放在訊息佇列中去,然後系統就會調用傳進去的參數mLoaderTask(LoaderTask類型)的run函數來處理這個訊息:調用loadAndBindAllApps成員函數,由於還沒有載入過應用程式,這裡的mAllAppsLoaded為false,於是調用loadAllAppsByBatch,構造一個CATEGORY_LAUNCHER類型的Intent,mContext.getPackageManager()獲得PackageManagerService的介面,通過這個PackageManagerService.queryIntentActivities介面來取回所有Action類型為Intent.ACTION_MAIN,並且Category類型為Intent.CATEGORY_LAUNCHER的Activity(前面啟動PackageManagerService時,會把系統中的應用程式都解析一遍,然後把解析得到的Activity都儲存在mActivities成員變數中,這裡通過這個mActivities變數的queryIntent函數返回符合條件intent的Activity,這裡要返回的便是Action類型為Intent.ACTION_MAIN,並且Category類型為Intent.CATEGORY_LAUNCHER的Activity)
  5. Launcher.bindAllApplications調用AllApps2D.setApps,setApps調用addApps函數來為上一步得到的每一個應用程式建立一個ApplicationInfo執行個體了,有了這些ApplicationInfo執行個體之後,就可以在案頭上展示系統中所有的應用程式了。到了這裡,系統預設的Home應用程式Launcher就把PackageManagerService中的應用程式載入進來了:當我們點擊Home按鍵時,便會響應Launcher.onClick函數調用showAllApps函數顯示應用程式圖示,把剛才載入好的應用程式以表徵圖的形式展示出來了。
  6. 當點擊這些應用程式圖示時,便會響應AllApps2D.onItemClick函數,然後調用Launcher.startActivitySafely函數來啟動應用程式
   



Android應用程式安裝與Launcher啟動機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.