最新Android Studio支持jni啦! 但是google上搜索资料是说使用experimental版本插件(Experimental Plugin User Guide)来集成jni模块,我试过的确好用,会自动帮你生成对应的jni方法,不用使用javah生成头文件,再用ndk工具编译出so库再使用了。但是experimental版本插件现在还在测试中,而且进度缓慢,另外对build.gradle的配置也和普通的不一样,不知道是否有不稳定的情况。
然而,最近有个同事在研究一门技术时发现普通的android gradle插件也可以加入jni模块,和experimental版本插件差不多。瞬间觉得很高大上,但是google有没用相关的说明,觉得奇怪,莫非也是在测试阶段?管它呢,先知道一下怎么玩再说。
运行环境
- Android Studio 2.0
- android build tool 插件版本:2.0.0(‘com.android.tools.build:gradle:2.0.0’)
- gradle 2.10
步骤
- 使用studio新建一个普通的android应用项目
检查local.properties文件中是否有指定ndk的路径,如无参考sdk路径配置ndk的路径,如:
12ndk.dir=/Users/suyouxiong/Library/Android/sdk/ndk-bundlesdk.dir=/Users/suyouxiong/Library/Android/sdk在build.gradle中添加ndk模块
12345678910111213android {compileSdkVersion 23buildToolsVersion "23.0.2"defaultConfig {... ...ndk {moduleName "hello-ndk"}}}此时sync会报错:
Error:(14, 0) NDK integration is deprecated in the current plugin.
Consider trying the new experimental plugin
Set “android.useDeprecatedNdk=true” in gradle.properties to continue using the current NDK integration从错误信息可以看到要么使用experimental版本插件(Experimental Plugin User Guide),要么是在gradle.properties添加
android.useDeprecatedNdk=true
配置。这里我们是要用平常的插件来集成jni,所以采用后面的解决方法。在项目根目录的gradle.properties文件添加android.useDeprecatedNdk=true
,再次sync问题解决。在
src/main
目录下创建jni
目录用于存放本地代码,也可以选中app之后执行File > New > Folder > JNI Folder
创建在MainActivity中加载jni模块并声明native方法:
12345static {System.loadLibrary("hello-ndk");}private native String getStringNative();此时studio会提示找不到该方法。使用快捷键
alt+enter
,这时会弹出解决方法列表,选择创建c方法,studio会自动创建一个和模块名相同的c文件,但并不会自动创建方法。手动编写c方法,如果没有显式去配置java方法和c方法的对应关系,c方法名默认应该是Java+包路径(.用下划线_替换)+类名+加方法名,对应
getStringNative
方法,这样写:12345JNIEXPORT jstring JNICALL Java_com_meizu_flyme_awesomendk_MainActivity_getStringNative(JNIEnv *env, jobject instance) {// TODOreturn (*env)->NewStringUTF(env, "Hello from JNI !");}ps:如果你是copy上面这段代码,注意方法名要和你应用的实际情况相符
在MainActivity中使用
getStringNative
方法,直接使用一个TextView来显示即可:12345678910@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);... ...TextView tv = (TextView) findViewById(R.id.hello_ndk);tv.setText(getStringNative());}运行,ok
jni代码调试
有个同事突然和我说现在studio可以调试本地代码,我立马感到吃惊。虽然我不写jni模块,但是可以让大家知道怎么回事啊。
首先在
build.gradle
中打开jni调试:1234567891011121314android {... ...buildTypes {release {... ...}debug {jniDebuggable true}}}选择
Run > Edit Configurations
,进入运行调试设置窗口,选择Debugger
便签页,在debug type
下拉选项中选择native
,此时你可能会看到下面的error(如果没有那么可以退出设置,跳过后面步骤直接debug运行调试了):studio给我们提供了快速解决方法,点击error信息后面的fix按钮,弹出相关包的安装信息,和安装sdk中的其它工具一样,选择
Accept
,点击下一步进行安装安装完成后回到
Run > Edit Configurations
窗口,发现error解决了,这时需要把debug type
选回Java
,因为app
这个运行配置应该对应java代码的(这是我后面才明白过来,在Android Application
下面还有个Android Native
,这个才是配置native运行配置的,前面的操作无非是要安装那个c++调试包)安装完之后点击
OK
按钮退出Run > Edit Configurations
窗口,回到主窗口,在运行配置选择下拉框就多出了native的配置项选择
app-native
,在c代码打上断点,开始调试咯进入
Run > Edit Configurations
窗口看看app-native
的配置,会发现其debug type
默认是Hybrid
,另外还有native
选择,经过测试选择native
也是可以调试的,但是只能调试c代码,不能调试java代码,而Hybrid
是都可以的(好方便)。
以上
想想还是附上源码作为参考吧:https://github.com/you-x/AwesomNdk