搭建軟體執行平臺以及IDE環境

邏輯貓發表於2018-12-13

     一、前述

     開發板:Android7.1.1開發平臺(附帶Android7.1.1系統原始碼)

     PC:win10作業系統

     IDE:AndroidStudio

     使用軟體:VisualBox虛擬機器,Ubuntu18.04穩定版系統

     Android系統介面互動定製有一大部分內容修改的是SystemUI、Launcher系統應用。比如說修改分屏或者狀態列圖示的時候需要修改SystemU或者主介面佈局則是設計到Launcher。為了省去了每次都要編譯原始碼的麻煩提高效率,可以把SystemUI、Launcher從系統原始碼抽取出來放在Android Studio中編譯執行。買過的一個開發板附帶了Android7.1.1原始碼,那麼就用這個原始碼來做開發。虛擬機器則安裝Ubuntu18.04用於編譯Android系統原始碼。

    二、分析依賴庫

     Launcher比較獨立一點, 直接拷貝出來放在Android Studio中執行即可。SystemUI由於依賴很多系統庫,直接拷貝出來則會出現大量的錯誤。SystemUI在原始碼中的目錄為:frameworks\base\packages\SystemUI。系統app原始碼編譯一般都是通過編譯Android.mk檔案,SystemUI的Android.mk檔案內容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
 
LOCAL_MODULE_TAGS := optional
 
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
    src/com/android/systemui/EventLogTags.logtags
 
LOCAL_STATIC_JAVA_LIBRARIES := Keyguard
LOCAL_JAVA_LIBRARIES := telephony-common
 
LOCAL_PACKAGE_NAME := SystemUI
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
 
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
LOCAL_RESOURCE_DIR := \
    frameworks/base/packages/Keyguard/res \
    $(LOCAL_PATH)/res
LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.android.keyguard
ifneq ($(SYSTEM_UI_INCREMENTAL_BUILDS),)
    LOCAL_PROGUARD_ENABLED := disabled
    LOCAL_JACK_ENABLED := incremental
endif
 
include frameworks/base/packages/SettingsLib/common.mk
 
include $(BUILD_PACKAGE)
 
ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
    include $(call all-makefiles-under,$(LOCAL_PATH))
endif

    可以看到其中依賴的三個包:

  1. LOCAL_STATIC_JAVA_LIBRARIES := Keyguard
  2. LOCAL_JAVA_LIBRARIES := telephony-common
  3. include frameworks/base/packages/SettingsLib/common.mk

    由於Keyguard以及SettingsLib這兩個包含res檔案工程,那麼直接以工程的形式匯入,而telephony-common直接以jar包的形式匯入。

    Keyguard的Android.mk檔案內容:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)

LOCAL_MODULE := Keyguard

LOCAL_CERTIFICATE := platform

LOCAL_JAVA_LIBRARIES := SettingsLib

LOCAL_PRIVILEGED_MODULE := true

LOCAL_PROGUARD_FLAG_FILES := proguard.flags

LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res

include $(BUILD_STATIC_JAVA_LIBRARY)

#include $(call all-makefiles-under,$(LOCAL_PATH))

 可以看到的依賴於SettingLib:LOCAL_JAVA_LIBRARIES := SettingsLib

三、Android Studio匯入SettingLib、KeyGuard、SystemUI原始碼

   

 四、編譯jar包以及系統簽名

    利用開發板自帶的shell指令碼一鍵編譯出所有的jar,所依賴的JAR包有以下幾個:
    framework.jar包對應的目錄是:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
    libcore.jar包對應的目錄是:out\target\common\obj\JAVA_LIBRARIES\core-libart_intermediates
    telephony-common.jar包對應的目錄是:out\target\common\obj\JAVA_LIBRARIES\telephony-common_intermediates

   匯入以上幾個包之後,執行正常。但當系統重啟之後無法正常啟動百思不得其解。於是乎百度了下,找到是由於未持有系統簽名。解決如下:

    Android的簽名檔案存放於系統原始碼的 build/target/product/security/目錄下。使用以下幾個即可:platform.pk8、platform.x509.pem。Android自帶的簽名工具為 signapk.jar,具體路徑為:out/host/linux-x86/framework/signapk.jar    以上APK具有系統許可權,重新簽名應該使用platform簽名檔案進行簽名。指令為:java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk。

    但是該命令在7.0以及之後的系統會出現no conscrypt_openjdk_jni in java.library.path錯誤。
    解決方法:在原始碼中拷貝prebuilts/sdk/tools/linux/lib64/libconscrypt_openjdk_jni.so到簽名的資料夾中,然後執行java -Djava.library.path=. -jar signapk.jar platform.x509.pem platform.pk8 app.apk app_sign.apk。(注意!該方法只在Linux操作環境中有效)。編譯出來的apk檔案push到系統 system/framework路徑,開發板重啟,正常執行!

五、編譯Framework.jar

     由於有時需要修改狀態列高度之類的而修改SystemUI又無法實現,那麼就需要編譯framework了。

     在虛擬機器中主要會涉及這三類:

      在目錄mm frameworks/base/core/res 編譯 framework-res.apk
      在目錄frameworks/base/ 下執行mm 編譯 framework.jar
      在目錄frameworks/base/services/java/ 執行mm 編譯  services.jar

     有需要的話可以push到開發板對應的資料夾,重啟即可生效:

     執行如下命令:
     adb push framework-res.apk /system/framework/
     adb push framework.jar /system/framework/
     adb push services.jar /system/framework/

六、總結

     搭建的開發環境能夠正常使用執行。還有很多東西需要改善:
    1、後期可以更好的使用Gradle指令碼,傻瓜式編譯執行apk
    2、熟悉Git以及搭建遠端Git伺服器。把原始碼編譯可以放到伺服器中編譯。
    3、就是更好的學習framework知識體系以及Android.mk知識。

相關文章