Android Gradle编译改为mk编译

最近出于工作需要,要将一个模块由gradle编译改为mk方式加入源码编译。遇到了一些问题,在这里记录一下。主要有以下几个问题:

  1. 项目中一些三方jar包的引用
  2. AIDL 文件的编译
  3. Dex 64K限制问题
  4. so 库文件的编译
  5. 根据编译版本类型编译不同的asset文件夹

1. 三方jar包的引用

#  fresco:libs/fresco.jar, 冒号前面的名字是随便取得,无所谓,后面跟上对应的jar包的路径,多个jar之间空格隔开
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := fresco:libs/fresco.jar   gson:libs/gson-2.3.1.jar 
include $(BUILD_MULTI_PREBUILT)

在需要引用地方:

# 这里引用的时候只需要引用上面定义的别名即可
LOCAL_STATIC_JAVA_LIBRARIES := \
    fresco \
    gson\

这里还有个问题:在gradle方式中 通过 compile 方式应用的三方库,我们当时并没有下载 jar 文件放到libs 文件夹下啊,咋办?

  • 其实 jar 包是被下载在项目的 External Libraries目录下,找到引用的 jar包,点右键 find in path,就得到了 jar 包的文件地址,把它塞到 libs 文件夹下,然后就在mk中像别的 jar 包一样处理就好了

2. AIDL 文件的编译

  • 最初我是按照下面这种方式将aidl文件加入编译,但是始终编译不过。
LOCAL_SRC_FILES := \
    $(call all-java-files-under, src) \
    src/main/aidl/com/test/module/IScanCallback.aidl \
    src/main/aidl/com/test/module/IScanInterface.aidl \
Couldn't find import for class com.test.module.IScanCallback

但是以前我也有类似的经历,编译AIDL这么写是OK的啊,问题出在哪了呢?倒腾了几个小时,经查:

Android.mk在编译简单的AIDL,即传递的参数只有基本数据类型时,上面的写法没有问题。

  • 我的AIDL代码如下:
// IScanCallback.aidl
package com.test.module;
interface IScanCallback {
    boolean myXXX(boolean isOk);
}
// IScanInterface.aidl
package com.test.module;
import com.test.module.IScanCallback;
interface IScanInterface {
    void  startXXX(String filePath);
    void registerCallback(IScanCallback cb);
    void unregisterCallback(IScanCallback cb);
}

问题可能就出现在了 IScanInterface.aidl中引用了com.test.module.IScanCallback并作为参数传递了。

  • 这种情况,正确的写法如下:
# 不仅要在LOCAL_SRC_FILES  标签后加入 aidl文件路径,还要加入LOCAL_AIDL_INCLUDES  标签
aidl_dirs = src/main/aidl
LOCAL_SRC_FILES := \
    $(call all-java-files-under, src) \
    src/main/aidl/com/test/module/IScanCallback.aidl \
    src/main/aidl/com/test/module/IScanInterface.aidl \
LOCAL_AIDL_INCLUDES  += $(LOCAL_PATH)/$(aidl_dirs)

3. Dex 64K限制问题

ERROR: Dex writing phase: classes.dex has too many IDs. Try using multi-dex  

DEX 64K 问题: 方法数超限65536
Android平台的Java虚拟机Dalvik执行Dex程序时,使用的是short类型来索引DEX文件中的方法。这就意味着单个Dex文件可被引用的方法总数被限制为64x1024, 即65536。其中包括:
Android Framework的方法 library的方法 我们自己写的方法 为突破这个限制,需要使用multidex来生成多个dex文件

在mk文件中添加以下两个标签即可

LOCAL_DX_FLAGS := --multi-dex
LOCAL_JACK_FLAGS := --multi-dex native

4. so 库文件的编译

和三方jar包的编译方式类似,只是标签不同

include $(CLEAR_VARS)
LOCAL_PREBUILT_LIBS := libaaaa:libs/arm64-v8a/lib_aaaa.so
LOCAL_PREBUILT_LIBS += libbbbb:libs/arm64-v8a/lib_bbbb.so
include $(BUILD_MULTI_PREBUILT)

在需要引用的地方:

LOCAL_JNI_SHARED_LIBRARIES := libaaaa   libbbbb

5. 根据编译版本类型编译不同的asset文件夹

这里主要是 LOCAL_ASSET_FILES标签的使用

ifeq ($(YOUR_JUDGEMENT),true)
LOCAL_ASSET_FILES     += assets/
else
LOCAL_ASSET_FILES     += assets-debug/
endif

6. 附上完整的mk文件:

LOCAL_PATH := $(call my-dir)

############### 三方jar包和so库的编译 ########################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := gson:libs/gson-2.3.1.jar  fresco:libs/fresco.jar
LOCAL_PREBUILT_LIBS := libaaaa:libs/arm64-v8a/lib_aaaa.so
LOCAL_PREBUILT_LIBS += libbbbb:libs/arm64-v8a/lib_bbbb.so
include $(BUILD_MULTI_PREBUILT)

#######################################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := \
    $(call all-java-files-under, src) \
    src/main/aidl/com/test/module/IScanCallback.aidl \
    src/main/aidl/com/test/module/IScanInterface.aidl \
 
######## 解决AIDL编译的问题 #############
aidl_dirs = src/main/aidl
LOCAL_AIDL_INCLUDES  += $(LOCAL_PATH)/$(aidl_dirs)

######## 根据需求编译不同的asset目录 ######
ifeq ($(YOUR_JUDGEMENT),true)
LOCAL_ASSET_FILES     += assets/
else
LOCAL_ASSET_FILES     += assets-debug/
endif

######## 三方jar包和so库文件的引用 #########
LOCAL_STATIC_JAVA_LIBRARIES := \
    gson \
    fresco \
    
LOCAL_JNI_SHARED_LIBRARIES := libaaaa   libbbbb

LOCAL_STATIC_ANDROID_LIBRARIES := \
    android-support-v4 \
    android-support-annotations \
    android-support-v7-recyclerview \
    android-support-v7-preference \
    android-support-v7-cardview \
    android-support-v7-appcompat \
    android-support-v7-palette \
    android-support-v14-preference \
    android-support-v17-preference-leanback \
    android-support-v17-leanback \

####### 解决 64K DEX限制问题  #######
LOCAL_DX_FLAGS := --multi-dex
LOCAL_JACK_FLAGS := --multi-dex native

LOCAL_PACKAGE_NAME := XXXXX
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true

LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PROGUARD_FLAG_FILES := proguard-rules.pro
include $(BUILD_PACKAGE)

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

具体 Android.mk 里面的标签还有很多,使用的过程中遇到问题的话会继续补充进来,使用方法网上相关的文章很多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,408评论 4 371
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,690评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,036评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,726评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,123评论 3 296
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,037评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,178评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,964评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,703评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,863评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,333评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,658评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,374评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,195评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,988评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,167评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,970评论 2 279

推荐阅读更多精彩内容