美文网首页Android求生之路
Android Gradle编译改为mk编译

Android Gradle编译改为mk编译

作者: 最忆是深秋 | 来源:发表于2018-08-11 16:24 被阅读559次

    最近出于工作需要,要将一个模块由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 里面的标签还有很多,使用的过程中遇到问题的话会继续补充进来,使用方法网上相关的文章很多。

    相关文章

      网友评论

        本文标题:Android Gradle编译改为mk编译

        本文链接:https://www.haomeiwen.com/subject/dvddbftx.html