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文件可被引用的方法总数被限制为64×1024, 即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 里面的标签还有很多,使用的过程中遇到问题的话会继续补充进来,使用方法网上相关的文章很多。

    原文作者:最忆是深秋
    原文地址: https://www.jianshu.com/p/8f00d4d692cd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞