将Android.mk工程迁移为gradle项目(apk化)

项目背景:

Android.mk 文件位于项目 jni/ 目录的子目录中,用于向编译系统描述源文件和共享库。

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。

MK项目的代码调试通常使用命令进行编译,有的时间比较长,并且不能debug。通过将Android.mk工程迁移为gradle项目,就可以在Android Studio上进行调试,在一定程度上提高了调试代码的速率。

明确作业内容:

1.将mk转换成gradle

2.解决编译错误:

资源错误;java文件找不到的错误(识别出依赖,并制作、导入jar包)

mk——gradle

1.定义编译成果

plugins {
    id 'com.android.application'
}
id 'com.android.application'   编译生成apk
id 'com.android.library'    编译生成aar
id 'maven-publish'   生成maven

2.定义常量

ext {
    APPS_TOOLS_MODEL = "BASIO"
    URBANO = "URBANO"
    EXPLORER = "EXPLORER"
    MIRAIE = "MIRAIE"
    RAFRE = "RAFRE"
    TORQUE = "TORQUE"
    BASIO = "BASIO"
}

有的时候,一个模块的代码仓里有多个机种的代码,虽然代码量比较大,但是比较便于维护。在mk和gradle中定义模块名即可控制代码的选择。

3.配置SDK版本

    compileSdk 31 //SDK编译版本

    defaultConfig {
        applicationId "xxx.xxx.xxxx"
        minSdkVersion 31 //最小SDK版本
        targetSdkVersion 31  //系统兼容
        versionCode 1
        versionName "0001.0001"
    }

4.apk打包

通过打包才能将apk安装到手机上

   signingConfigs {
        debug {
            storeFile file('/home/tsdl/Project/AndroidStudioProject/MkToApk/android_debug_key/platform.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        config {
            storeFile file('../../android_debug_key/platform.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }

5.构建类型

buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.config //指定release时的signingConfigs对应的配置名
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        debug {
            minifyEnabled false
            signingConfig signingConfigs.config
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        applicationVariants.all {
            variant ->
                variant.outputs.all {
                    output ->
                        if (variant.buildType.name == "release") {
                            outputFileName = "DeskClock-${defaultConfig.versionName}.apk"
                        }
                }
        }

    }

6.配置java版本

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

7.资源设置

sourceSets {
        main{
            java.srcDirs = ["src/main/java"]
            java.srcDirs += ["src/main/java/MODEL"]
            assets.srcDirs = ["src/main/assets"]
            res.srcDirs = ["src/main/res"]
            manifest.srcFile "src/main/AndroidManifest.xml"

            if (APPS_TOOLS_MODEL == EXPLORER) {
//                res.srcDirs += ["src/main/MODEL/EXPLORER/res"]
//                java.srcDirs += ["src/main/java/EXPLORER"]
                manifest.srcFile "src/main/MODEL/AndroidManifest.xml"
            }
            ...
            else if (APPS_TOOLS_MODEL == BASIO){
                res.srcDirs += ["src/main/MODEL/BASIO/res"]
                java.srcDirs += ["src/main/java/BASIO"]
                manifest.srcFile "src/main/MODEL/BASIO/AndroidManifest.xml"
            }else {
//                res.srcDirs += ["src/main/MODEL/BASE/res"]
//                java.srcDirs += ["src/main/java/BASE"]
            }

            aidl.srcDirs = ["src/main/java/com/android/alarmclock/IRegisterReceiverService.aidl",
                            "src/main/java/com/android/deskclock/IAlarmInitShutdownService.aidl"]

        }
    }

gradle版本不同,写法略有不同。注意java、res等文件路径(项目结构)。

由于我的代码仓里有多个机种的代码,所以我在sourceSets里进行了区分,但是gradle编译的时候资源不能重复,为了防止这类的报错,我就先把其他机种的代码拿掉,等做其它机种的时候再投入进去。其实资源重复的这个问题可以解决。

release.resources.srcDirs=['src/main/xxxxx']

通过设置优先级,选择调用那个res资源

8.lint配置

    lintOptions {
        // true--错误发生后停止gradle构建
        abortOnError false
    }

9.导入资源包

dependencies {
    //noinspection GradleCompatible
    implementation 'com.android.support:support-v13:28.0.0'
    if (APPS_TOOLS_MODEL == EXPLORER ||
            APPS_TOOLS_MODEL == CONCOURSE ||
            APPS_TOOLS_MODEL == URBANO ||
            APPS_TOOLS_MODEL == CEIJI){
        implementation 'designlib_kon:0001.0001'
    }else if (APPS_TOOLS_MODEL == MIRAIE){
        implementation 'designlib_blue35:0001.0001'
    }else if (APPS_TOOLS_MODEL == BASIO){
        implementation 'designlib_biro:0001.0001'
    }
    implementation fileTree(dir: "libs", include: ["*.aar"])
    implementation fileTree(dir: "libs",include: ['*.jar'])
    implementation 'com.android.support:support-v4:28.0.0'
}

在mk文件中,通过LOCAL_STATIC_JAVA_LIBRARIES及include xxx/xxx/xxx.mk引入哪些资源库,按照对应的方式在gradle中引入。

编译错误——资源错误

通常会报Duplicate resources资源重复的错误,因为gradle编译不能两个资源的名称不能一样。自己权衡一下,删掉其中一个就行。

再有就是手机厂商有自己定制的theme之类的,不导入进去,也会资源报错。但是对于这个主题的改变,对于bug的调试影响不打,可以自己找个主题替换一下,或者没用到,直接注释掉就行。

编译错误——java文件未导入成功

一般这种导包错误和一些方法未找到都是因为引用了其他组(如:framework等的api)

导入这些资源通常有这几种方法:

1.看所依赖代码的mk文件,编译生成出来的东西,如果生成lib、jar,直接编译,然后将生成的包放到项目的libs文件夹下,并在gradle的dependencies中引入此包。

2.如果是生成apk的代码仓,需要以同样的方式进行一下mk转换gradle,并生成arr包,再导入到项目的libs文件夹下。

3.通过maven的方式来打包项目(依赖嵌套比较严重的时候,推荐使用;要是本项目频繁使用此包,不是很推荐使用maven)

猜你喜欢

转载自blog.csdn.net/m0_50408097/article/details/123088576
今日推荐