安卓 jni 开发 —— Android Studio 打包 so 的坑

博客: 安卓之家
微博: 追风917
CSDN: 蒋朋的家
简书: 追风917

安卓开发坑无限
我心依旧,不变
向前

jni 开发的坑


这两天要搞安卓下的串口读写,这块涉及到了 jni 开发,我找了两个项目,导入 as 修改后上传到了 github

AndroidSerialPortSample

AndroidSerialPort

jni 坑尤其多,编译器不好选择,windows 下用 vs,as,vs双管齐下可好?卡死了。

mbp 用户该如何搞,虚拟机开 windows,呵呵。

有个大神就是用 atom 开发 jni,然后 gdb 调试,这才是真爱啊,膜拜下。

as 打包 so


关于 as 的打包,之前总结过:Android Studio 多渠道打包、自动版本号及 gradlew 命令的基本使用

今天的问题主要是 jni 下的打包,遇到了几个坑。

1 打包特定平台 so 到 apk 包

开发多 jni 的同学,都知道,as 默认会把七个平台 —— armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86_64 全部打到 apk 包里,拆开包就会在 libs 文件夹下看到各平台都有:

我在这里遇到了一个问题
由于我还用到了百度导航,因此还有百度导航的 so 文件(只有 armeabi 平台),又因为我的测试手机是 arm64,导致 apk 安装运行后,百度导航初始化失败。

原因呢,也很简单:因为 apk 包里有 arm64-v8a, 因此手机会把该文件夹下的 so 放到 系统 libs 文件夹下使用,而该文件夹只有 jni 开发生成串口的 so,没有百度导航的 so,因此 app 运行后找不到百度导航所需要的 so,导致百度导航初始化失败。关于安卓开发下 so 的正确使用姿势可以访问这里:

关于Android的.so文件你所需要知道的

解决方法,自然就是只打包 armeabi 的 so 到 apk。上面的文章里也给出了解决方法,配置下 gradle 脚本即可:

    splits {
        abi {
            enable true
            reset()
            include 'armeabi'   //只打 armeabi 
            universalApk true //true 打一个通用包,包含全部七个平台
        }
    }

    // map for the version code
    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]

    android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride =
                    project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode
        }
    }

这样配置好后,就解决了我们的问题,只会把 armeabi 平台的 so 打包进 apk。这样运行 apk 后,程序运行一切正常。

2 自定义包名

上面配置好后,打包的 apk 的名字是这样的:app-armeabi-debug.apk,现在我需要自定义这个包名

要求:只打包 armeabi 平台 so 进 apk,并且 apk 包名自定义为 导航-release--armeabi-v1.3.7-Google_Play-2016-03-18

bunnyblue 大神给出的思路是:打包好后,写个打包工具,然后修改 apk,重新签名

这个坑,我还没有填满,木有解决,有知道的麻烦告知一下咯

3 其他坑

在解决第一个问题的时候,掉入了另一个坑,用到了一个插件:

android-native-dependencies

该插件确实可以只打特定平台的包,并且可以一个,两个,多个平台,但是会把项目里其他的 so 都删除。也就是我用该插件后,可以只打包串口的 so,但同时蛋疼的是把我百度导航的 so 都删除了,这可如何是好啊,因此没有用该插件咯

如果你用过该插件,并且能解决我的第二个问题,也麻烦告知下咯,谢谢

分享是一种美德,更是一种生活方式!!

也许你会说我是一个梦想者,但我不是唯一的一个。

悦分享,越快乐^_^

欢迎交流,转载请注明出处,谢谢!

你可能感兴趣的:(Android,Android,Studio,gradle)