背景:
馬哥學員朋友以前在vip群里,有問道如何在Android.bp中添加條件判斷,在工作中經常需要一套代碼兼容發貨目標版本,即代碼都是公共的一套,但是需要用這一套代碼集成到各個產品設備上
但是這個產品設備可能面臨比較多的情況,例如有以下幾種:
1、產品設備可能面臨android大版本的差異,新老版本的api可能都有差異,都寫到代碼中無法編譯通過
2、產品本身有一些特別定制的功能,可能面臨只是在某些機型有這個功能
面臨上面要適配多個機型差異的問題,大家可能第一時間會想到用不同的代碼分支不就行了么,但是大家注意如果用不同的代碼分支同時意味著每個分支的代碼你都需要進行維護,維護工作量極大,也就是經常可能修改了一個bug,做了一個新需求,你不得不同步一遍到多個分支,這樣一旦機型多了,差異多了,你的維護成本會越來越多。
所以使用分支差異來管理是不可取的,一般還是希望一個公共分支可以實現對多個機型的適配,那么這個該怎么實現呢?
這個其實也需要分情況來進行考慮,主要有2種情況:
情況1:代碼層面可以區分,通過相關產品類型屬性值等代碼端走不同的分支
情況2:代碼編譯依賴api或者庫都有差異,即會有編譯上的差別情況,那么這種就一定需要通過Android.mk,Android.bp中進行相關的條件判斷才可以
下面我們主要針對情況2的編譯差異進行講解相關方法。
Android.mk配置條件判斷
Android.mk這個實現判斷編譯比較簡單
1 獲取當前安卓版本號?
通過$(PLATFORM_VERSION)獲取系統版本值,例如:
13對應Android 13(Tiramisu),14對應Android 14(UpsideDownCake)?
2? 條件分支實現?
使用ifeq/else根據版本號選擇依賴文件
案例1:使用不通過的依賴jar
# 示例:Android 13及以上使用新JAR,低版本使用舊JAR
ifeq ($(PLATFORM_VERSION),13)LOCAL_JAVA_LIBRARIES := new_sdk_jar
elseLOCAL_JAVA_LIBRARIES := legacy_sdk_jar
endif
案例1:使用不通過的依賴代碼文件夾
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)# Android 14使用新功能類,其他版本使用兼容類
ifeq ($(PLATFORM_VERSION),14)LOCAL_SRC_FILES := $(LOCAL_PATH)/src/new_feature/*.java
elseLOCAL_SRC_FILES := $(LOCAL_PATH)/src/compat/*.java
endifLOCAL_MODULE := my_library
include $(BUILD_JAVA_LIBRARY)
Android.bp配置條件判斷
Android.mk是可以直接有條件判斷,但Android.bp中的條件判斷相對就復雜的多,下面是整個源碼:
目錄結構如下:
test@test:~/aosp/get_display_ids$ tree
.
├── aidl
│ └── android
│ └── hardware
│ └── display
│ ├── DisplayInfo.aidl
│ └── IDisplayManager.aidl
├── Android.bp ---核心bp文件
├── src
│ ├── DisplayBase.cpp
│ ├── DisplayBase.h
│ ├── main1.cpp --sdk版本大于33的編譯的cpp文件
│ └── main.cpp --sdk版本小于等于33的編譯的cpp文件
└── version.go ---主要判斷版本然后控制編譯不同cpp的go文件5 directories, 9 files
邏輯都在version.go文件核心源碼(完整源碼分享vip群中)
再看看Android.bp
// add start
bootstrap_go_package {name: "soong-version",pkgPath: "android/soong/version",deps: ["soong-android","soong-cc",],srcs: ["version.go",],pluginFor: ["soong_build"],
}filegroup {name: "libdms_client_aidl",srcs: ["aidl/**/*.aidl"],path: "aidl"
}cc_library {name: "libdms_client",srcs: [ "src/DisplayBase.cpp",":libdms_client_aidl"],aidl: {export_aidl_headers: true,local_include_dirs: ["aidl"],},export_include_dirs: ["src",],shared_libs: ["libbinder","liblog","libutils",],
}cc_version_binary {name: "version_defaults",
}
// add endcc_binary {name: "get_display_ids",defaults: ["version_defaults"],//依賴version_defaultsshared_libs: ["libbinder","liblog","libutils","libdms_client",],
}
aosp13上驗證結果
代碼差異:
編譯時候:
執行時候:
aosp14上驗證結果
代碼差異:
編譯時候:
執行時候:
因為aosp14版本是sdk為34
更多framework實戰開發干貨,請關注下面“千里馬學框架”