不知道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)了

這次我們需要的是
com.android.support.constraint:constraint-layout:1.1.3,所以我們搜com.android.support.constraint看看:
點(diǎn)擊進(jìn)去之后可以看到:

然后我們就得到了
constraint-layout-1.1.3.aar:
根據(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ò)程。