在各平臺應用開發過程中,隨著業務的功能增加,不免會涉及到非公開的
API
依賴,針對某些應用或廠商系統的適配,每個版本都需要投入精力去排查,CoCollider
可以讓我們的適配效率從幾個星期提升到幾小時即可完成。
專案已開源:
☞ Github:https://www.github.com/iofomo/fireyer ☜
☞ Github:https://www.github.com/iofomo/wing ☜
如果您也喜歡,別忘了給我們點個星。
01. 寫在前面
在Android
平臺(後續會支援iOS
平臺)日常開發過程中,不免會接觸到一些 Hidden
(或私有函式和類)的類,JVM
層透過反射,Native
則透過查詢函式 symbol
來完成。特別是涉及系統Framework
層和底層庫較多的實現(特別是安全產品和系統工具類應用),成為每次系統和廠商ROM
更新適配的重災區,嚴重影響適配效率。
以往,開發同學要麼先一個個自行排查程式碼後再提交測試,這個過程重複,耗時且容易遺漏。要麼先讓測試同學先進行用例覆蓋測試,然後開發同學透過BUG
來進行分析,這會導致整個團隊效率更加低下。
由於我們虛擬化產品的特性,工程中涉及系統和應用適配的介面眾多,工作量很大,主要有兩部分:
- 如何快速尋找到系統新增的模組,感興趣的可以檢視我們的另一個開源專案 【ASeeker】 https://www.github.com/iofomo/aseeker
- 如何快速定位現有使用的
API
是否已發生變化,這就是【CoCollider】
要解決的問題。
CoCollider
已經在我們內部使用,極大提升我們系統適配效率,原本需要幾個星期的工作量,現在只需幾小時便可適配完成,原理簡單,堪稱適配效率神器。Android 15
釋出在即,現在分享給大家。
CoCollider
同樣適用於其他平臺(如:iOS)和某些深度定製的應用版本適配。
02. 我們需要
對於系統的API
,我們的需求是:
- 類的屬性是否有變化。
- 類的成員屬性是否有變化。
- 類的方法屬性是否有變化。
Native
庫和函式是否存在。
對於開發工程師的工作量,首次需要在原始碼中新增註釋標籤,這個工作不可省略,卻一勞永逸。後續需要在每次涉及適配的程式碼處加上@CoCollider
標籤就行。
Java程式碼標籤格式:
格式:
// @CoCollider {class name},{-/+}{field name/method name},...
範例:
# 僅檢視類是否變更
// @CoCollider android.utils.Abc
# 僅檢視類所有成員是否變更
// @CoCollider android.utils.Abc,-*
# 檢視類和某成員或方法是否變更(支援多個)
// @CoCollider android.utils.Abc,-mFile
// @CoCollider android.utils.Abc,-mFile,mName
// @CoCollider android/utils/Abc,-mFile
// @CoCollider android.utils.Abc,+getFile,-mName
// @CoCollider android/utils/Abc,+getFile,+getName,-mName
# 支援預設自動填充:(按照順序依次填充)
Class.forName("android.utils.Abc");// @CoCollider
# 等同於:// @CoCollider android.utils.Abc
ReflectUtils.getStaticField("android.utils.Abc", "mName");// @CoCollider ,-
# 等同於:// @CoCollider android.utils.Abc,-mName
Native 程式碼標籤格式:
格式:
// @CoCollider ~{lib name},{-/+}{field name/method name},...
範例:
# 檢視方法是否變更
// @CoCollider ~libc.so,+open
// @CoCollider ~/system/lib/libc.so,+open
// @CoCollider ~/system/lib/libc.so,+open,+close
# 支援預設自動填充:(按照順序依次填充)
utils_dlsym("libc.so", "open");// @CoCollider ~,+
# 等同於:// @CoCollider ~libc.so,+open
utils_dlsym("open");// @CoCollider ~libc.so,+
# 等同於:// @CoCollider ~libc.so,+open
03. 配置執行
-
電腦下載配置
wing
。 -
手機安裝
Fireyer
,或整合CoCollider
模組的應用,連結adb
。 -
掃描程式碼:
# 命令格式:掃描當前目錄下的程式碼(預設支援 h/c/cpp/java/kt/aidl,也可以追加檔案型別) $ wing -cocollider scan $ wing -cocollider scan /home/space # 或 $ python ./cocollider.py scan $ python ./cocollider.py scan /home/space # 在當前目錄輸出結果 >>> cocollider-scan-20241023-112044.txt
-
解析執行:
# 命令格式:呼叫 Fireyer 應用 $ wing -cocollider run /home/cocollider-scan-20241023-112044.txt # 或 $ python ./cocollider.py run /home/cocollider-scan-20241023-112044.txt # 在當前目錄輸出結果 >>> cocollider-run-20241023-112044.txt
-
使用對比工具檢視結果即可快速定位變更內容。
04. 掃描結果
cocollider-scan-20241023-112044.txt
中的檔案內容為:
############################################################
= android.utils.Abc
- mFile
> application/fireyer/test/test1.java,14
- mName3
> application/fireyer/test/test1.java,14
- mPath
> application/fireyer/test/test1.java,14
############################################################
= android.utils.Abc1
- mFile
> application/fireyer/test/test1.java,5
...
05. 執行結果
cocollider-run-20241023-112044.txt
中的檔案內容(已對class
,lib
庫,function
,field
和method
排序,便於使用對比工具對比)
############################################################
~ libwilhelm.so
[OK]
+ _ZN7androidxx6BufferE
[OK], public final class libcore.io.Linux
> cmpt/xxx/jni/xxx/jni/src/xxx.cpp,362
+ _ZN7android1xx6BufferE
[OK], public final class libcore.io.Linux
> cmpt/xxx/jni/xxx/jni/src/xxx.cpp,350
############################################################
= ohos.abilityshell.HarmonyApplication
[Fail]
- applicationHandler
[Fail]
> scene/xxx/xxx.java,36
############################################################
= ohos.system.Parameters
[Fail]
+ nativeGet
[Fail]
> scene/xxx.cpp,250
...
06. 對比結果
分別在不同版本系統執行 python cocollider.py run
之後,使用對比工具(如:Beyond Compare
)對內容進行比較檢視,可以快速找到新增,修改和刪除項,從而可以快速進行排查和修復。