APK及相關的Android路徑


APK(Android package,wiki  chs):android安裝包,由aapt(Android Assert Packaging Tool,已集成到build-tools工具集中)把AndroidManifest.xml、資源文件、lib動態鏈接庫、dex(Dalvik二進制字節碼)等歸檔成的zip壓縮包。

assets:對應項目工程asset目錄下的文件,可以使用AssetManager獲取     注:其下的main.obb.png為一個壓縮方式為僅存儲的標准zip文件

lib:包含適用於不同處理器的第三方動態鏈接庫,這里邊可以有多個子目錄。如:armeabi、armeabi-v7a、 arm64-v8a,、x86,、x86_64以及mips

METE-INF:存放簽名證書等信息;其中包含兩個簽名文件(CERT.SF和CERT.RSA)和一個manifest文件(MANIFEST.MF)

        jdk1.8.0_77\bin\keytool.exe -printcert -file %apkdir%\CERT.RSA  // 查看當前apk的簽名信息

res:包含那些沒有被編譯到resources.arsc的資源(如:應用圖標、字符串表等)

AndroidManifest.xml:二進制格式的manifest文件

classes*.dex:Dalvik EXcutable file,Dalvik虛擬機執行程序,java文件先編譯為class文件,然后打包成dex二進制字節碼文件。一個APK中有多個dex文件。

resources.arsc:存儲編譯好的資源,包括項目工程中的res/values目錄里的xml文件,它們都被編譯成二進制格式,也包括一些路徑,指向那些沒有被編譯的資源,比如layout文件和圖片

 

Android系統目錄結構

  • /init                     系統啟動文件
  • /bin                    常用的系統本地命令(二進制) 如:du、ls、mv等
  • /system
    • build.prop       系統設置和變更屬性
    • app               安裝的系統應用所在的目錄
    • bin                常用的系統本地命令(二進制) 如:ps、cp、rm等
    • etc                系統配置文件
      • hosts          用於配置IP或域名的重定向文件
    • font               字體目錄
    • framework    Java平台架構核心庫,jar包和odex優化的文件
    • lib                 32位系統底層共享庫,.so庫文件
    • lib64             64位系統底層共享庫,.so庫文件
      • egl
        • libGLES_android.so
      • libart-compiler.so
      • libart-dexlayout.so
      • libart.so
      • libc++.so
      • libc.so
      • libstdc++.so
      • lib_malloc_debug.so
      • lib_malloc_hooks.so
      • libEGL.so
      • libGLESv1_CM.so
      • libGLESv2.so
      • libGLESv3.so
      • ... ...
    • xbin               不常用的系統管理工具,相當於linux的/sbin
    • media
      • audio  鈴聲,提示音等音頻文件, .ogg
        • notifications    通知
        • ui                   界面
        • alarms            警告
        • ringtones        鈴聲
    • usr                   用戶文件夾,包含共享、鍵盤布局、時間區域
      • keychars
      • keylayout
      • share
      • srec        配置
      • ......
    • vendor          廠商文件
      • build.prop
      • app       廠商自帶應用所在目錄
      • bin        廠商自帶命令工具
      • etc
      • lib
      • lib64
        • egl
          • eglSubDriverAndroid.so
          • libGL_adreno.so
          • libGLESv1_CM_adreno.so
          • libGLESv2_adreno.so
          • libq3dtools_adreno.so
          • libq3dtools_esx.so
          • libQTapGLES.so  
        • libjson.so
        • ... ...
  • /etc  -->  軟鏈接指向  /system/etc
  • /vendor -->  軟鏈接指向 /system/vendor
  • /dev                       存放設備節點文件
  • /proc                    全局系統信息
  • /data                 用戶軟件和各種數據
    • local/tmp  臨時目錄,無權限要求
    • app                普通程序安裝目錄
    • data
      • <package_name>
        • files                     Context.getFilesDir() ,Context.openFileOutput() 獲取的目錄,應用安裝目錄下
        • cache                  Context.getCacheDir()  獲取的目錄,應用安裝目錄下,系統會自動在內存不足或目錄大小達到特定數值時自動清理。
        • shared_pref        Context.getSharedPreferences() 建立的preferences文件(xml)存放目錄
    • anr                應用發生ANR(Applicaiton is Not Responding)時,Android將問題點的堆棧寫入到traces.txt文件中
    • property        其中persist.sys.timezone記錄系統時區
  • /sdcard  -->  軟鏈接   SD卡的FAT32文件系統掛載到此目錄
    • Android
      • data
        • <package_name>   應用的額外數據,應用卸載時自動刪除。
          • files      Context.getExternalFilesDir()獲取的目錄。設置->應用->具體應用詳情-> 清除數據  操作對象就是這個目錄。
          • cache    Context.getExternalCacheDir()獲取的緩存目錄。設置->應用->具體應用詳情-> 清除緩存  操作對象就是這個目錄。

可在Android Studio的View菜單 -- Tool Windows -- Device File Explorer面板中查看手機上整個文件目錄(手機無需root   更多信息詳見這里

 注:文件夾圖標的右上角帶箭頭為一個軟鏈接,右下角帶問號的為一個文件

 

內部存儲(Internal Storage)   // 在手機內部,屬於手機自帶存儲空間的一部分

/data/app  // 應用程序安裝的目錄。安裝時,系統的PackageManagerService(PMS)進程會把apk文件復制到該目錄

1. com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==     // 字符串S72Tv4IGEow5LtbwxPQHpQ是隨機字符串,每次安裝都會變化

2. base.apk為原始的Android安裝包。app運行時的資源從該文件中讀取。

3. 在安裝apk時,PMS會將apk中的so動態鏈接庫釋放到/data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==/lib/arm64

   游戲so動態鏈接庫的路徑搜索路徑依次為:/data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==/lib/arm64, /data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64, /product/lib64

4. 首次運行app時,會將apk中的classes*.dex編譯釋放到/data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==/oat/arm64中,會生成出3個文件:base.vdex、base.odex、base.art

   .vdex未壓縮DEX 代碼,以及一些旨在加快驗證速度的元數據(省去重新校驗apk中dex文件合法性的過程 )。Android 8引入。
   .odex對於dalvik虛擬機,存放的是JIT后的優化后的字節碼(Optimized Dalvik EXcutable file);對於AOT Runtime,存放的是經過AOT(Ahead Of Time)編譯后的本地機器碼(即:oat文件,一種私有的ELF文件格式)。

    注1:為了保證安裝速度,在安裝時並沒有AOT;而是當app啟動運行一小段時間,收集了足夠多的jit 熱點方法信息時,

              Android會在后台重新進行dex2oat(該文件在/system/bin/dex2oat,是Android Art Runtime的重要模塊), 將熱點函數(Hot Code)編譯成odex本地機器碼

    注2:odex + vdex = 全部java源碼。隨着更多的vdex的java代碼被AOT成odex,其size會逐漸變小

   .art (可選):包含APK中列出的某些字符串和類的 ART 內部表示,記錄app啟動熱點函數相關地址,用於加快app啟動速度。

 

/data/data  // 該目錄存放應用程序的私有數據

對於設備中每一個安裝的 App,系統都會在內部存儲空間的 data/data 目錄下以應用包名為名字自動創建與之對應的文件夾。

用戶卸載 App 時,系統自動刪除 data/data 目錄下對應包名的文件夾及其內容。

data/data/包名/cache: 存放的 APP 的緩存信息

context.getCacheDir(); // 返回/data/data/包名/cache目錄路徑

data/data/包名/databases: 存放 APP 的數據庫信息

context.getDataDir(); // 返回/data/data/包名/databases目錄路徑
context.getDatabasePath(name); // 獲取指定數據庫對象
context.deleteDatabase(name); // 刪除指定數據庫對象

data/data/包名/files: 存放 APP 的文件信息

context.getFilesDir(); // 返回/data/data/包名/files目錄路徑
context.deleteFile(name); // 刪除指定文件對象
context.fileList(); // 查詢所有文件對象

data/data/包名/shared_prefs: 存放 APP 內的 SharedPreferences

context.getSharedPreferences(name,mode) //返回指定的SharedPreferences對象
context.deleteSharedPreferences(name) // 刪除指定的SharedPreferences

 

一些內部存儲的根目錄

Environment.getDataDirectory(); // 返回/data目錄
Environment.getDownloadCacheDirectory(); // 返回/cache目錄
Environment.getRootDirectory(); // 返回/system目錄

 

外部存儲(External Storage)   //  非root下,只要是能看得到,都是外部存儲

該存儲可能是可移除的存儲介質(如:SD 卡)或內部(不可移除)存儲。 保存到外部存儲的文件是全局可讀取文件。當用USB連接到計算機並以傳輸文件后,可由用戶修改這些文件。

外部存儲在Android 文件系統中是/sdcard目錄(只是一個快捷方式),真正的目錄是 /storage/emulated/0 文件夾

/sdcard -> /storage/self/primary -> /mnt/user/0/primary -> /storage/emulated/0

注1:對於不同版本的Android系統,/sdcard指向的真正目錄有一些不同。

注2:Android設備一般都有內置 SD 卡,有一些設備同時也提供外置 SD 卡接口(用於插入的外置內存卡,其對應的路徑形如:/storage/AFE0-2E94)

Environment.getExternalStorageDirectory();  //  返回/storage/emulated/0目錄

Environment.getExternalStoragePublicDirectory(DIRECTORY_ALARMS);  //  返回/storage/emulated/0/Alarms目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_DCIM);  //  返回/storage/emulated/0/DCIM目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS);  //  返回/storage/emulated/0/Download目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_MOVIES);  //  返回/storage/emulated/0/Movies目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC);  //  返回/storage/emulated/0/Music目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_NOTIFICATIONS);  //  返回/storage/emulated/0/Notifications目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES);  //  返回/storage/emulated/0/Pictures目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_PODCASTS);  //  返回/storage/emulated/0/Podcasts目錄
Environment.getExternalStoragePublicDirectory(DIRECTORY_RINGTONES);  //  返回/storage/emulated/0/Ringtones目錄

 

/sdcard/Android/data/包名    // App外部存儲私有目錄

context.getExternalFilesDir();  //外部存儲私有目錄/sdcard/Android/data/包名/files  UE4的FString GExternalFilePath全局變量即為該目錄   一般存儲長時間保存的數據   對應“設置”->“應用”-> “應用詳情”里面的“清除數據”選項
context.getExternalCacheDir(); //外部存儲私有目錄/sdcard/Android/data/包名/cache  一般存儲臨時緩存數據   對應“設置”->“應用”-> “應用詳情”里面的“清除緩存”選項

默認情況下,系統並不會自動創建外部存儲空間的應用私有目錄。開發人員需在需要時,通過 SDK 提供的 API 創建該目錄文件夾和操作文件夾內容

當用戶卸載 App 時,系統也會自動刪除外部存儲空間下的對應 App 私有目錄文件夾及其內容,不會留下垃圾。

 

/sdcard/Android/obb/包名   // App外部存儲obb目錄

context.getObbDir(); // 返回App的外部存儲obb目錄

 

/sdcard/UE4Game   // UE4Game外部存儲目錄

在UE4Game外部存儲目錄中,Test1項目的目錄結構如下:

 

APK安裝的4種方式

① 系統應用安裝:開機時加載系統的APK和應用,沒有安裝界面

② 網絡下載應用安裝:通過各種market應用完成,沒有安裝界面

③ ADB工具安裝:即通過Android的SDK開發tools里面的adb.exe程序安裝,沒有安裝界面 

注1:對應的window為:com.miui.securitycenter/com.miui.permcenter.install.AdbInstallActivity

注2:需要在【開發者選項】中打開【USB安裝】

注3:小米10手機可通過如下設置來關閉“USB安裝提示”的確認   -- step1:【開發者選項】中【關閉MIUI 優化】  step2:重啟手機     step3:【應用設置】--【授權管理】,右上角設置里面,關閉【USB安裝管理】

 

④ 通過第三方應用來安裝:通過SD卡里的APK文件安裝(比如雙擊APK文件觸發),有安裝界面,系統默認已經安裝了一個安裝卸載應用的程序(packageinstaller.apk)

 

APK安裝過程

1. 拷貝apk文件到指定目錄

在Android系統中,apk安裝文件是會被保存起來的,默認情況下,用戶安裝的apk首先會被拷貝到 /data/app 目錄下。/data/app目錄是用戶有權限訪問的目錄,在安裝apk的時候會自動選擇該目錄存放用戶安裝的文件。

而系統出廠的apk文件則被放到了 /system 分區下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,該分區只有Root權限的用戶才能訪問,這也就是為什么在沒有Root手機之前,我們無法刪除系統出廠的app的原因了。

2. 解壓apk,拷貝文件,創建應用的數據目錄

apk在安裝的時候,會將app的依賴的第三方動態鏈接庫拷貝到/data/app/包名-XXXXXXXXXXXXXX==/lib/平台名的目錄中。

然后,在/data/data/目錄下創建應用程序的數據目錄(以應用的包名命名),存放應用的相關數據,如數據庫、xml文件、cache、二進制的so動態庫等等。

3. 解析apk的AndroidManifinest.xml文件並寫入/data/system/packages.xml

/data/system/packages.xml類似於Windows的注冊表,這個文件是在解析apk時由writeLP()創建的,里面記錄了系統的permissions,以及每個apk的name,codePath,flags,ts,version,uesrid等信息。

這些信息主要通apk的AndroidManifest.xml解析獲取,解析完apk后將更新信息寫入這個文件並保存,下次開機直接從里面讀取相關信息添加到內存相關列表中。當有apk升級,安裝或刪除時會更新這個文件。

<package name="com.tencent.mf.test1" codePath="/data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==" nativeLibraryPath="/data/app/com.tencent.mf.test1-S72Tv4IGEow5LtbwxPQHpQ==/lib" primaryCpuAbi="arm64-v8a" publicFlags="940097094" privateFlags="0" ft="173e7953470" it="173e795b2e4" ut="173e795b2e4" version="1" userId="10815" installer="com.miui.packageinstaller">
    <sigs count="1" schemeVersion="2">
        <cert index="34" key="3082033d30820225a003020102020425c2be86300d06092a864886f70d01010b0500304e310b300906035504061302636e310b3009060355040813026764310b300906035504071302737a310b3009060355040a13026d66310b3009060355040b13026d66310b3009060355040313026d663020170d3230303130363037343934385a180f32323933313032313037343934385a304e310b300906035504061302636e310b3009060355040813026764310b300906035504071302737a310b3009060355040a13026d66310b3009060355040b13026d66310b3009060355040313026d6630820122300d06092a864886f70d01010105000382010f003082010a0282010100b4455215e09e7cdb7830cebe51c0d79e6f5cb22e96d7ce11f3d1f40e1ef43be245f49fbabb1af8efeddb823dc7ca1273724421c478a315e01b57f69a3d642c062bd879e096904fb379692c6d62cb032b14d6ed687a53b620dcf6ddb925fea65bdad3eff2244786d3b22dbfb2e7cc77424336048c852b7e85bdf41d5a05da231528ae3bfebb6752a92cf895073b38c3b43e1f9f6d217d24bab868575b36d7efd29739ad5b34b4d7f53a9c2cbe2b8db349f730b0cda090b91e57a54cdc5803577ac84159f7144a69902f12bd8da4986a85aab9020bab076f5f2254fd57c75c3c8aaeb4b4eda6ba9c9369e08e77f4f99c801e8819c341743de17dce558470e5b19f0203010001a321301f301d0603551d0e0416041491e0d5be16fcfcfa80e39b370a70ec05236828ff300d06092a864886f70d01010b05000382010100919b40fc021831a196726201e528c4a3ceefce44890ec9c07e543b757e0a0fde0c1230c34e3883104ff7e3cac4d0fcf42dbb4cefaaf97853e04313d1a611b5198b8d969c00b041bb2de8484b4140c5d80a7bdcbe66bd03fbb37c78b794078fc5d512b0298144864691d01cbd12d3f052548c83cc6d76c62379ce1fe7b48c24af4f1cf0ddf35faa4f833ab556c60d1793a432cfb64e475fe01dad59417d1b6a3f97f24de881dc65842e361e2074edf23d80228ce5f242bd485dc60b43999c2328e11608376a60eacc9a0228356aa008a1d95c57d3526591dbd352aa46b06f9c21f90e1967a65ccd70859d9a420ee5b0cb62ca7ef18c4fa0da8534577e7677f7b8" />
    </sigs>
    <perms>
        <item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" />
        <item name="android.permission.BLUETOOTH" granted="true" flags="0" />
        <item name="android.permission.INTERNET" granted="true" flags="0" />
        <item name="com.android.vending.CHECK_LICENSE" granted="true" flags="0" />
        <item name="android.permission.BLUETOOTH_ADMIN" granted="true" flags="0" />
        <item name="android.permission.CHANGE_WIFI_STATE" granted="true" flags="0" />
        <item name="android.permission.ACCESS_NETWORK_STATE" granted="true" flags="0" />
        <item name="android.permission.VIBRATE" granted="true" flags="0" />
        <item name="android.permission.ACCESS_WIFI_STATE" granted="true" flags="0" />
        <item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
    </perms>
    <proper-signing-keyset identifier="577" />
</package>

4. 顯示icon圖標

Launcher應用程序負責從PackageManagerService服務中把這些安裝好的App取出來,並以快捷圖標的方式在桌面上展現出來。

如小米10上的Launcher window為:com.miui.home/.launcher.Launcher

 

SIM卡

SIM卡即電話芯片卡,對應某個手機號,上面也能存放一些個人隱私數據:如聯系人、短信等。

第三方App必須申請相應的權限才能訪問SIM卡上數據。

 

參考

深度探究apk安裝過程-多圖

一文看懂 Android APK 安裝的原理

Davilk and ART 01 解釋 

Android 存儲路徑淺析 

Android 存儲路徑你了解多少

Android基礎 你必須了解的應用文件目錄 

Android SIM卡聯系人的增刪改查操作 

Android系統目錄結構 

關閉 MIUI 煩人的 USB 安裝提示 

Android ART dex2oat 淺析 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM