下面使用Android Studio开发JNI的一个简单Demo。
1.新建Android Project
- 通过Android Studio Wizard 创建一个普通的项目
这里将这两个默认选项勾掉
- 定义有一个native 方法,MainActivity内容如下:
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public native String HelloJNI();
}
2.编译生成.h
这里要编译一下生成MainActivity.class文件
- 在控制台将光标定位到当前项目的app/src/main下
- 执行下面的生成.h文件的命令
javah -d jni -classpath E:\Android_Sdk\platforms\android-25\android.jar;../../build/intermediates/classes/debug com.example.myapplication.MainActivity
javah –help
这里
-d jni指明要在当前目录下创建jni文件夹存储生成的头文件;
-classpath …\android.jar,由于这里编译的MainActivity中使用了Android 的api,所以要将android.jar加入编译路径(这里使用的是buildSdkVersion对应的android.jar);
如果有多个依赖的jar使用”;”分割;
“;”前后不要留有空格;
要生成头文件的MainActivity的完全限定名 (com. example. myapplication.MainActivity)前要留有空格.
在src/main/jni下面生成com_example_myapplication_MainActivity.h
在Android Studio Android视图中cpp文件夹下面也会出现
3.实现编译so文件需要的各种文件&&进行编译
- 实现.h文件中定义的接口
在cpp目录下创建HelloJNI.c实现.h文件中定义的接口,
其内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "com_example_myapplication_MainActivity.h"
/*
* Class: com_example_myapplication_MainActivity
* Method: HelloJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_HelloJNI
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"Hello I'm from JNI2");
}
在cpp下完成Android.mk文件
Android.mk用于向ndk描述你写的c/c++源文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloJNI
LOCAL_SRC_FILES :=HelloJNI.c
include $(BUILD_SHARED_LIBRARY)
- 在cpp下完成Application.mk文件
APP_ABI := all
- 编译生成so文件
ndk-build.cmd
3.调用&&测试
- 在MainAcitivity中引入HelloJNI
MainActivity的完整代码如下所示:
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView=new TextView(this);
setContentView(textView);
textView.setText(HelloJNI());
}
public native String HelloJNI();
static {
System.loadLibrary("HelloJNI");
}
}
执行,错误信息如下:
Error:Execution failed for task ':app:compileDebugNdk'.
> Error: Your project contains C++ files but it is not using a supported native build system.
Consider using CMake or ndk-build integration with the stable Android Gradle plugin:
https://developer.android.com/studio/projects/add-native-code.html
or use the experimental plugin:
http://tools.android.com/tech-docs/new-build-system/gradle-experimental.
- 修改gradle添加ndk,支持c++编译
在build.gradle(app:module)下android/defaultConfig下面添加如下内容:
ndk{
moduleName "HelloJNI"
}
sourceSets.main{
jni.srcDirs=[]
jniLibs.srcDir 'src/main/libs'
}
运行测试ok.
- 另一种测试方法
可能会有疑问,我调用qq,jpush等服务添加so文件时,并不需要修改build.gradle 文件啊?咱们这里怎么就需要修改了呢?是这样的咱们这里添加了c++文件,如果按照如下方式稍作调整,可以屏蔽掉对build.gradle文件的修改.
- 删除创建的jni文件夹及其下面的所有内容
- 将libs下面所有包含so文件的文件夹都移动到app/src/main/jniLibs下,不存在jniLibs文件夹,创建一个就ok了.