放棄用Android.mk的方式編譯APK

不知道Android從哪個(gè)版本開始,在AOSP中使用mm編譯,變得無(wú)比緩慢,嚴(yán)重拖慢了開發(fā)節(jié)奏。
想要加快mm編譯除了提高電腦的硬件配置之外,還可以使用Android Studio搭配Gradle的方式編譯Apk。

從0開始

我最初學(xué)習(xí)開發(fā)Android的時(shí)候,都是用的Eclipse+ADT插件編譯調(diào)試的,目前這種方式已經(jīng)被摒棄,不推薦了。
因此接下來(lái)只講Android Studio + Gradle的方式。
先不要管目前手頭的代碼是什么方式,或者什么目錄結(jié)構(gòu)的,我們的目的要把老的目錄結(jié)構(gòu)轉(zhuǎn)換成標(biāo)準(zhǔn)的Android Studio的結(jié)構(gòu),并且要支持 Android.mk 編譯

使用AndroidStudio創(chuàng)建一個(gè)Project,然后放到AOSP中進(jìn)行mm編譯能生成apk,并順利運(yùn)行

AndroidStudio生成的Project的目錄結(jié)構(gòu):

├── app
│   ├── app.iml
│   ├── build
│   │   ├── generated
│   │   ├── intermediates
│   │   ├── outputs
│   │   ├── reports
│   │   └── tmp
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src
│       ├── androidTest
│       ├── main
│       └── test
├── build
│   └── intermediates
│       └── lint-cache
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── GradleAndroidmkDemo.iml
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
build.gradle轉(zhuǎn)換成Android.mk

先看以下app目錄下的build.gradle:

apply plugin: 'com.android.application'

android {
    // compileSdkVersion 27, 要跟你AOSP的版本匹配,不能高與AOSP的版本,否則容易出問(wèn)題
    // 下面的 minSdkVersion 21 和 targetSdkVersion 27 也需要注意
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.andforce.gradleandroidmkdemo"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

我們可以看到,其實(shí)主要依賴了:

    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
尋找依賴庫(kù)

1:從ASOP源碼中查找
在AOSP代碼中的framework/support存放了很多庫(kù):

.
├── Android.mk
├── annotations
│   ├── AndroidManifest.xml
│   ├── Android.mk
│   ├── api
│   ├── build.gradle
│   ├── external-annotations
│   └── src
.
.
.

├── v13
│   ├── AndroidManifest.xml
│   ├── Android.mk
│   ├── api
│   ├── build.gradle
│   ├── java
│   ├── lint-baseline.xml
│   └── tests
├── v14
│   ├── Android.mk
│   └── preference
├── v17
│   ├── Android.mk
│   ├── leanback
│   └── preference-leanback
├── v4
│   ├── AndroidManifest.xml
│   ├── Android.mk
│   ├── build.gradle
│   └── lint-baseline.xml
├── v7
│   ├── Android.mk
│   ├── appcompat              #這里就是我們需要的
│   ├── cardview
│   ├── gridlayout
│   ├── mediarouter
│   ├── palette
│   ├── preference
│   └── recyclerview
└── wear
    ├── AndroidManifest.xml
    ├── Android.mk
    ├── api
    ├── build.gradle
    ├── lint-baseline.xml
    ├── proguard-rules.pro
    ├── README.txt
    ├── res
    ├── res-public
    ├── src
    └── tests

可以看到正好有我們此次用到的appcompat-v7,其他什么v4 之類也有。
但是沒(méi)有看到constraint-layout,這時(shí)候就要祭出神器了:
https://mvnrepository.com/
想要依賴什么,直接把包名或者庫(kù)名放到紅色框內(nèi)搜一下就出來(lái)了

image.png

這次我們需要的是com.android.support.constraint:constraint-layout:1.1.3,所以我們搜com.android.support.constraint看看:
image.png

點(diǎn)擊進(jìn)去之后可以看到:
image.png

然后我們就得到了constraint-layout-1.1.3.aar
image.png

根據(jù)經(jīng)驗(yàn),僅僅有了constraint-layout還是不行,還需要一個(gè)constraint-layout-solver的jar

同理,我們?cè)谏厦娴木W(wǎng)站也能得到:constraint-layout-solver-1.1.3.jar

開始編寫 Android.mk

在工程的根目錄下(與app目錄同級(jí)別),創(chuàng)建Android.mk

LOCAL_PATH:= $(call my-dir)

# 清除除了LOCAL_PATH外的所有變量
include $(CLEAR_VARS)

# support包的根目錄,因?yàn)榫幾g時(shí)我們只能引用來(lái)自于framework的support包
support_library_root_dir := frameworks/support

# 設(shè)置src 和 res
LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java)
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, app/src/main/res) \
    $(support_library_root_dir)/v7/appcompat/res

# 指定Manifest文件
LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml

# 重復(fù)資源自動(dòng)覆蓋
LOCAL_AAPT_FLAGS += \
    --auto-add-overlay \
    --extra-packages android.support.v7.appcompat \
    --extra-packages android.support.constraint

# frameworks/support/ 下有v7 和 v4的源碼
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v7-appcompat android-support-v4
# constraint-layout需要的jar
LOCAL_STATIC_JAVA_LIBRARIES += constraint-layout-solver

# 依賴庫(kù),aar
LOCAL_STATIC_JAVA_AAR_LIBRARIES := constraint-layout

# Apk名稱
LOCAL_PACKAGE_NAME := GradleAndroidmkDemo

# BUILD_PACKAGE 是一個(gè)預(yù)定義的宏,里面包含編譯一個(gè)APK的腳本。
include $(BUILD_PACKAGE)

include $(CLEAR_VARS)

# 構(gòu)建依賴的jar
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := constraint-layout-solver:app/mk/libs/constraint-layout-solver-1.1.3.jar
# 構(gòu)建依賴的aar
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += constraint-layout:app/mk/aars/constraint-layout-1.1.3.aar

include $(BUILD_MULTI_PREBUILT)

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

如果沒(méi)有什么特殊情況,我們把這個(gè)Project放到packages/apps下,進(jìn)行mm編譯就能生成apk了,至此我們的第一步就走完了。

Project依賴多個(gè)Moudle怎么辦?

我們創(chuàng)建一個(gè)module叫mylibrary,然后讓app依賴它:

├── Android.mk
├── app
│   ├── app.iml
│   ├── build
│   ├── build.gradle
│   ├── mk
│   ├── proguard-rules.pro
│   └── src
├── build
│   └── intermediates
├── build.gradle
├── gradle
│   └── wrapper
├── GradleAndroidmkDemo.iml
├── gradle.properties
├── gradlew
├── gradlew.bat
├── LICENSE
├── local.properties
├── mylibrary
│   ├── build
│   ├── build.gradle
│   ├── libs
│   ├── mylibrary.iml
│   ├── proguard-rules.pro
│   └── src
├── README.md
└── settings.gradle

此時(shí),我需要求改Android.mk,讓其能把mylibrary編譯進(jìn)去。

# 添加mylibrary的src和res
LOCAL_SRC_FILES += $(call all-java-files-under, mylibrary/src/main/java)
# 這里需要注意,由于library的擁有自己的package name,因此會(huì)生成自己的R文件,不能直接把res路徑直接加上,需要向下面這樣寫
LOCAL_AAPT_FLAGS += --auto-add-overlay -S $(addprefix $(LOCAL_PATH)/, \
    mylibrary/src/main/res) --extra-packages com.andforce.mylibrary

到現(xiàn)在,我們已經(jīng)完成了依賴Module的編譯過(guò)程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容