生活随笔
收集整理的這篇文章主要介紹了
代码Overlay机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊打開鏈接
?代碼overlay機制意思是,將我們在Android原生代碼上修改過的文件,單獨放在一個目錄下,而在編譯代碼的時候就會去檢測這個目錄下的文件,如果這個目錄下的文件與原生有相同的文件,那么就將這個文件放入編譯的源文件中,而將原生相同文件名的文件從編譯的源文件中去除。
?這樣做有什么好處呢,比如我們和客戶合作,在我們自己的代碼上加了某一個功能,于是動了原生的代碼,而我們的客戶有時候不需要這個功能,那么我們必須在原生上面去除這個代碼,比如用git revert等。
?但是如果我們有這樣一個代碼overlay的機制,我們只要將我們修改的代碼文件去除就可以,這樣系統就會把原生的文件放入編譯的源文件中加入編譯。
1.建立overlay的文件
比如我們需要對原生的PowerManagerService進行修改,首先我們先在服務器代碼根目錄建立一個比如:overlay這樣一個目錄,原生PowerManagerService的目錄: frameworks/base/services/core/java/com/android/server/power/PowerManagerService,
那么如果我們對這個文件修改,先拷貝一份PowerManagerService代碼放在目錄:overlay/frameworks/base/services/core/java/com/android/server/power/PowerManagerService,
然后再去對這個目錄下的PowerManagerService進行修改。
2.修改Android.mk文件
?修改好了代碼之后,就是修改編譯的Android.mk文件,修改這文件分為兩步,第一步是將我們修改代碼加入編譯,第二步是將原生相同文件從編譯中去除。
2.1將修改的代碼加入編譯
?我們還是舉例上面的PowerManagerService,其對應的Android.mk在目錄:
frameworks/base/services/core
我們先來看下原生的Android.mk文件:
[html]?view plain
?copyLOCAL_PATH?:=?$(call?my-dir)????include?$(CLEAR_VARS)????LOCAL_MODULE?:=?services.core????LOCAL_SRC_FILES?+=?\??????$(call?all-java-files-under,java)?\??????java/com/android/server/EventLogTags.logtags?\??????java/com/android/server/am/EventLogTags.logtags????LOCAL_JAVA_LIBRARIES?:=?telephony-common??LOCAL_STATIC_JAVA_LIBRARIES?:=?tzdata_update????include?$(BUILD_STATIC_JAVA_LIBRARY)??
我們先在修改這個文件:
LOCAL_SRC_FILES這個變量代碼參與編譯的文件,因此我們第一步就是將我們的文件放入這個變量中:
[html]?view plain
?copyservices_ext_subdirs?:=?$(addprefix?../../../../overlay/,?$(LOCAL_PATH)/)????services_ext_files?:=?$(call?all-java-files-under,$(services_ext_subdirs))????LOCAL_SRC_FILES?+=?$(services_ext_files)??
上面代碼中LOCAL_PATH代表當前目錄:frameworks/base/services/core
因此要找到我們的overlay代碼目錄,先要跳出frameworks這層,因此在LOCAL_PATH前面加了../../../../overlay/這個前綴就到了overlay/frameworks/base/services/core目錄了,我們再查找這個目錄下的java文件,加入到LOCAL_SRC_FILES這個變量中就把我們修改的文件加入到編譯中了。
?
2.2將原生相同文件從編譯中去除
下面我們需要將原生相同文件從編譯中去除,也就是把文件從LOCAL_SRC_FILES這個變量中移除。
我們來看下代碼實現:
[html]?view plain
?copyempty?:=????services_ext_overlay_files?:=?$(subst?$(services_ext_subdirs),$(empty),$(services_ext_files))????LOCAL_SRC_FILES?:=?$(filter-out?$(services_ext_overlay_files),?$(LOCAL_SRC_FILES))??
先把前面上一節中找到的java文件中前綴overlay/frameworks/base/services/core的直接把這個前綴替換掉了,可以理解是直接刪除了這個前綴。
比如PowerManagerService現在變成:
java/com/android/server/power/PowerManagerService
最后一行利用filter-out將上面這個文件從LOCAL_SRC_FILES中去除,也就是將原生的文件從編譯中去除。
?
這樣就達到了代碼overlay的目的。
3.例子(修改PowerManager、IPowerManager.aidl、PowerManagerService)
當然這里只是修改了PowerManagerService,下面我們通過PowerManager、IPowerManager.aidl整個修改來說下這個代碼overlay機制。
首先我們先修改IPowerManager.aidl:新增一個printPower接口
[java]?view plain
?copyinterface?IPowerManager??{??.............??????????????void?boostForPerformance(int?cpu_nr,?int?duration);??????void?printPower();??}??
下面是PowerManager.java中的修改:
[java]?view plain
?copy.......??????public?void?printPower()?{??????????try?{??????????????mService.printPower();??????????}?catch?(RemoteException?e)?{??????????}??????}??......??
當然這兩個文件時overlay,我們需要重新放在overlay/frameworks/base/services/core/java/android/os/IPowerManager.aidl;
overlay/frameworks/base/services/core/java/android/os/PowerManager.java
3.1 修改frameworks/base/Android.mk
下一步我們就看frameworks/base/Android.mk里面的修改:
[java]?view plain
?copyinclude?$(CLEAR_VARS)????#?FRAMEWORKS_BASE_SUBDIRS?comes?from?build/core/pathmap.mk??LOCAL_SRC_FILES?:=?$(call?find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS))????#overlay??ifeq?($(LEADCORE_OVERLAY),true)??base_file_overlay_prefix?:=?$(addprefix?../../overlay/,?$(LOCAL_PATH)/)??base_file_overlay_subdir?:=?$(addprefix?$(base_file_overlay_prefix),?$(FRAMEWORKS_BASE_SUBDIRS))??$(warning?$(base_file_overlay_subdir))??overlay_java_file?=?$(call?find-other-java-files,$(base_file_overlay_subdir))??LOCAL_SRC_FILES?+=?$(overlay_java_file)????empty?:=??base_overlay_files?:=?$(subst?$(base_file_overlay_prefix),$(empty),$(overlay_java_file))??$(warning?$(base_overlay_files))????LOCAL_SRC_FILES?:=?$(filter-out?$(base_overlay_files),?$(LOCAL_SRC_FILES))??endif??
下面再來看看aidl文件的overlay:
[html]?view plain
?copyLOCAL_SRC_FILES?+=?\??????core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl?\??????core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl?\??????core/java/android/accounts/IAccountManager.aidl?\??????core/java/android/accounts/IAccountManagerResponse.aidl?\??????core/java/android/accounts/IAccountAuthenticator.aidl?\??????core/java/android/accounts/IAccountAuthenticatorResponse.aidl?\??????core/java/android/app/IActivityContainer.aidl?\??????core/java/android/app/IActivityContainerCallback.aidl?\??????core/java/android/app/IActivityController.aidl?\??????..........????#aidl?files?overlay???ifeq?($(LEADCORE_OVERLAY),true)?//宏開關??//定義了一個變量用來去除原生的aidl文件的??LOCAL_SRC_FILES?:=?$(filter-out?$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES),?$(LOCAL_SRC_FILES))??//加入overlay下對應原生去除的aidl文件??LOCAL_SRC_FILES?+=?$(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES)??//打印調試??$(warning?$(base_file_overlay_prefix)$(FRAMEWORKS_BASE_OVERLAY_AIDL_FILES))??endif??
前PowerManager.java可以做到自動化,為什么aidl做不到呢?因為在base的Android.mk中aidl都是一個一個選出來的,就連同一目錄有的參與編譯,有的不參與編譯,為了簡單起見做了一個變量FRAMEWORKS_BASE_OVERLAY_AIDL_FILES來保存去除原生aidl文件。
3.2 系統變量定義
下面我們看下這個變量的定義:其實在build/core/pathmap.mk
[html]?view plain
?copyFRAMEWORKS_BASE_OVERLAY_AIDL_FILES?:=?\??????????core/java/android/os/IPowerManager.aidl??
順便看下宏開關的定義在build/core/envsetup.mk
[html]?view plain
?copyLEADCORE_OVERLAY?:=?true??
最后就是PowerManagerService.java的編譯,前面分析過了,這邊再簡單介紹下:
先在PowerManagerService.java中修改PowerManagerService里的BinderService增加一個接口如下:
[java]?view plain
?copyprivate?final?class?BinderService?extends?IPowerManager.Stub?{?????????.........?????@Override??????????public?void?printPower()?{??????Slog.e(TAG,?"printPower");?????????}??........??
3.3修改frameworks/base/services/core/Android.mk
下面就是修改frameworks/base/services/core/Android.mk文件
[html]?view plain
?copyLOCAL_PATH?:=?$(call?my-dir)????include?$(CLEAR_VARS)????LOCAL_MODULE?:=?services.core????LOCAL_SRC_FILES?+=?\??????$(call?all-java-files-under,java)?\??????java/com/android/server/EventLogTags.logtags?\??????java/com/android/server/am/EventLogTags.logtags????$(warning?$(LOCAL_PATH))????#overlay??ifeq?($(LEADCORE_OVERLAY),true)??services_ext_subdirs?:=?$(addprefix?../../../../overlay/,?$(LOCAL_PATH)/)??$(warning?$(services_ext_subdirs))????services_ext_files?:=?$(call?all-java-files-under,$(services_ext_subdirs))??LOCAL_SRC_FILES?+=?$(services_ext_files)??$(warning?$(services_ext_files))????empty?:=??services_ext_overlay_files?:=?$(subst?$(services_ext_subdirs),$(empty),$(services_ext_files))??$(warning?$(services_ext_overlay_files))????LOCAL_SRC_FILES?:=?$(filter-out?$(services_ext_overlay_files),?$(LOCAL_SRC_FILES))??endif????LOCAL_JAVA_LIBRARIES?:=?telephony-common??LOCAL_STATIC_JAVA_LIBRARIES?:=?tzdata_update????include?$(BUILD_STATIC_JAVA_LIBRARY)??
這樣整個修改power就完成了。
總結
以上是生活随笔為你收集整理的代码Overlay机制的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。