Android 64 bit的一些兼容性分析
Android 64 bit系統的一些兼容性分析
0x0:前言
Android L之後android開始了支持64bit的系統,現在64位的手機越來越多,基本上現在出的新機都是64位的了,所以64位將會是一個趨勢,但是對於對於開發者來說,64位android你真的了解么?64位系統是如何無縫兼容32位app的?
0x1:32位兼容分析
首先在init.zygote32_64.rc裡面有這兩條開機啟動的服務
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
這兩個進程在系統中就是傳說中的zygote進程,所有進程的孵化器,zygote對應app_proccess32,zygote64對應app_proccess64
顧名思義,android所有的應用進程都是fork zygote而來的
- 那麼,當我們啟動一個app時,系統是如何選擇運行32位模式還是64位模式的,為什麼有些app的父進程是zygote,有些是zygote64呢?*
通過看系統源碼,從系統啟動一個app開始,可以發現系統啟動一個應用是通過ActivityManagerService中startProcessLocked方法,主要通過Process中的startViaZygote方法,這個方法最終是向相應的zygote進程發出fork的請求 zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
其中,openZygoteSocketIfNeeded(abi)會根據abi的類型,選擇不同的zygote的socket監聽埠。zygote32位監聽的埠就是–socket-name=zygote
zygote64就是–socket-name=zygote_secondary這個abi就是決定該app是fork zygote 還是fork zygote64,這兩種模式就決定該app運行在何種環境。於是,我們繼續跟蹤abi是從哪裡傳過來的,發現這個參數在ApplicationInfo的primaryCpuAbi中決定。而這個值是PackageManagerService在scanPackageLI的時候傳進來的。最終,可以發現這個值是由apk的native 庫決定的,可以得出一個判斷邏輯:
如果apk中的native庫中含有arm64-v8a,則以64位的模式執行,fork zygote64如果沒有,則看有沒有armeabi-v7a,armeabi這兩個,如果有,則以32位模式執行,fork zygote如果apk中這三個庫都沒有,則默認以64位模式執行。0x2:結論:
**對於android開發者,我們應該要知道些什麼呢?
**1、64位系統本來是為了更快地執行指令,因此,如果我們想提升app在64位機器運行的效率,編譯so的時候最好把arm64-v8a編譯出來,在Application.mk裡面加上APP_ABI = APP_ABI := armeabi armeabi-v7a arm64-v8a,當然,這個會對包size有一定的影響。2、如果開發者考慮更多的是兼容性的話,特別是引起第三方的sdk的時候,如果sdk沒有arm64-v8的庫引入來,那麼就最好不要把 arm64-v8a編譯進去,否則在64位機器會出現一些問題,比如:java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/xxx.so" is 32-bit instead of 64-bit 3、64位和32位運行環境的差異:動態鏈接庫查找路徑:32位的環境是LD_LIBRARY_PATH=/vendor/lib:/system/lib;64位的環境是LD_LIBRARY_PATH=/vendor/lib64:/system/lib64;因此,在編寫native層代碼的時候,如果有一些代碼硬編碼了lib裡面的so路徑的時候,比如硬編碼了/system/lib/libc.so 這個路徑,在64位運行環境執行就會出錯>>>>閱讀全文
推薦閱讀:
※證明論學習筆記5:賦值系統
※這是一份收藏量超過2萬6的計算機科學學習筆記
※2017春季北大算分期末考試
※使用U盤的注意事項