【Android應用開發】-(9)應用程式安裝解除安裝原理
本文粗體部分來自網路上的一篇文章,已不知出處,知道的告知,在此謝謝原作者。引出安裝解除安裝的原理之前,先實現一個簡單的安裝解除安裝應用程式的功能。文章是我之前寫的一篇部落格,這裡就不在敘述,只補充幾點:
1、由於程式碼中用到了PackageInstallObserver,PackageInstallObserver在Eclipse中是不能呼叫的,必須在Linux環境下編譯好系統後才能編譯此應用程式。
2、Android4.0安裝的api以及和2.3的不同,多了個引數。感興趣的可以從哪看PackageInstaller中的程式碼或者檢視api。
-----------------------------分割線--------------------------------------
應用安裝是智慧機的主要特點,即使用者可以把各種應用(如遊戲等)安裝到手機上,並可以對其進行解除安裝等管理操作。APK是Android Package的縮寫,即Android安裝包。APK是類似Symbian Sis或Sisx的檔案格式。通過將APK檔案直接傳到Android模擬器或Android手機中執行即可安裝。
Android應用安裝有如下四種方式
1.系統應用安裝――開機時完成,沒有安裝介面
2.網路下載應用安裝――通過market應用完成,沒有安裝介面
3.ADB工具安裝――沒有安裝介面。
4.第三方應用安裝――通過SD卡里的APK檔案安裝,有安裝介面,由packageinstaller.apk應用處理安裝及解除安裝過程的介面。
應用安裝的流程及路徑,應用安裝涉及到如下幾個目錄:
1.system/app 系統自帶的應用程式,無法刪除
2.data/app 使用者程式安裝的目錄,有刪除許可權。安裝時把apk檔案複製到此目錄
3.data/data 存放應用程式的資料
4.Data/dalvik-cache 將apk中的dex檔案安裝到dalvik-cache目錄下(dex檔案是dalvik虛擬機器的可執行檔案,其大小約為原始apk檔案大小的四分之一)
安裝過程:複製APK安裝包到data/app目錄下,解壓並掃描安裝包,把dex檔案(Dalvik位元組碼)儲存到dalvik-cache目錄,並data/data目錄下建立對應的應用資料目錄。
解除安裝過程:刪除安裝過程中在上述三個目錄下建立的檔案及目錄。
一、系統應用安裝:
PackageManagerService處理各種應用的安裝,解除安裝,管理等工作,開機時由systemServer啟動此服務
(原始檔路徑:android\frameworks\base\services\java\com\android\server\PackageManagerService.java)
PackageManagerService服務啟動的流程:
1. 首先掃描安裝“system\framework”目錄下的jar包
1. scanDirLI(mFrameworkDir,PackageParser.PARSE_IS_SYSTEM,scanMode | SCAN_NO_DEX);
2.第二步掃描安裝“system\app”目錄下的各個系統應用
scanDirLI(mSystemAppDir,PackageParser.PARSE_IS_SYSTEM, scanMode);
3.第三步掃描“data\app”目錄,即使用者安裝的第三方應用
scanDirLI(mAppInstallDir, 0, scanMode);
4.第四步掃描" data\app-private"目錄,即安裝DRM保護的APK檔案(目前沒有遇到過此類的應用)。
scanDirLI(mDrmAppPrivateInstallDir,0, scanMode | SCAN_FORWARD_LOCKED);
安裝應用的過程
1.scanDirLI(Filedir, int flags, int scanMode) 遍歷安裝指定目錄下的檔案
2.scanPackageLI(FilescanFile, File destCodeFile, FiledestResourceFile, int parseFlags,int scanMode) 安裝package檔案
3.scanPackageLI(File scanFile, File destCodeFile, FiledestResourceFile, PackageParser.Package pkg, intparseFlags, int scanMode)
通過解析安裝包parsePackage獲取到安裝包的資訊結構
4.mInstaller.install(pkgName,pkg.applicationInfo.uid,pkg.applicationInfo.uid); 實現檔案複製的安裝過程
(原始檔路徑:frameworks\base\cmds\installd\installd.install)
二、從market上下載應用:
Google Market應用需要使用gmail賬戶登入才可以使用,選擇某一應用後,開始下載安裝包,此過程中,在手機的訊號區有進度條提示,下載完成後,會自動呼叫Packagemanager的介面安裝,呼叫介面如下:
public voidinstallPackage(final Uri packageURI, final IPackageInstallObserver observer,final int flags)
final Uri packageURI:檔案下載完成後儲存的路徑
final IPackageInstallObserver observer:處理返回的安裝結果
final int flags:安裝的引數,從market上下載的應用,安裝引數為-r (replace)
installPackage介面函式的安裝過程:
1.public voidinstallPackage(final Uri packageURI, final IPackageInstallObserverobserver, final int flags,final String installerPackageName)
final String installerPackageName:安裝完成後此名稱儲存在settings裡,一般為null,不是關鍵引數
2.FiletmpPackageFile = copyTempInstallFile(packageURI, res);
把apk檔案複製到臨時目錄下的臨時檔案
3.private voidinstallPackageLI(Uri pPackageURI,
int pFlags, boolean newInstall,String installerPackageName,
File tmpPackageFile, PackageInstalledInfo res)
解析臨時檔案,獲取應用包名pkgName = PackageParser.parsePackageName(
tmpPackageFile.getAbsolutePath(), 0);
4.判斷如果帶有引數INSTALL_REPLACE_EXISTING,則呼叫replacePackageLI(pkgName, tmpPackageFile, destFilePath,destPackageFile, destResourceFilepkg, forwardLocked,newInstall, installerPackageName, res)
5.如果沒有,則呼叫installNewPackageLI(pkgName,tmpPackageFile, destFilePath,destPackageFile, destResourceFile, pkg,forwardLocked, newInstall, installerPackageName, res);
6.privatePackageParser.Package scanPackageLI( File scanFile, File destCodeFile, FiledestResourceFile, PackageParser.Package pkg, intparseFlags, int scanMode)
scanPackageLI以後的流程,與開機時的應用安裝流程相同。
三、從ADB工具安裝
Android Debug Bridge (adb) 是SDK自帶的管理裝置的工具,通過ADB命令列的方式也可以為手機或模擬器安裝應用,其入口函式原始檔為pm.java(原始檔路徑:android\frameworks\base\cmds\pm\src\com\android\commands\pm\pm.java)
ADB命令列的形式為adb install <path_to_apk> ,還可以帶安裝引數如:"-l""-r" "-i" "-t"
函式runInstall()中判斷引數
"-l"――INSTALL_FORWARD_LOCK
"-r"——INSTALL_REPLACE_EXISTING
"-i" ——installerPackageName
"-t"——INSTALL_ALLOW_TEST
我們常用的引數為-r,表示覆蓋安裝手機上已安裝的同名應用。從market上下載的應用,也是直接傳入這個引數安裝的。
runInstall與market呼叫同樣的介面完成應用安裝。
public voidinstallPackage(android.net.Uri packageURI,android.content.pm.IPackageInstallObserver observer, int flags,java.lang.String installerPackageName)
四、第三方應用安裝――通過SD卡里的APK檔案安裝
把APK安裝包儲存在SD卡中,從手機裡訪問SD卡中的APK安裝包,點選就可以啟動安裝介面,系統應用Packageinstaller.apk處理這種方式下的安裝及解除安裝介面流程,
PackageInstallerActivity負責解析包,判斷是否是可用的Apk檔案
建立臨時安裝檔案/data/data/com.android.packageinstaller/files/ApiDemos.apk
並啟動安裝確認介面startInstallConfirm,列出解析得到的該應用基本資訊。如果手機上已安裝有同名應用,則需要使用者確認是否要替換安裝。
確認安裝後,啟動InstallAppProgress,呼叫安裝介面完成安裝。
pm.installPackage(mPackageURI,observer, installFlags);
其它:
1. PackageManagerService.java的內部類AppDirObserver實現了監聽app目錄的功能:當把某個APK拖到app目錄下時,可以直接呼叫scanPackageLI完成安裝。
2.手機資料區目錄“data/system/packages.xml”檔案中,包含了手機上所有已安裝應用的基本資訊,如安裝路徑,申請的permission等資訊。