上篇文章在android6.0系统中,实现了Java和C++方法的互相调用。这篇文章利用Android studio 2.2 实现Java和C方法的互相调用。
目标:
1,java通过JNI机制可以调用C中的方法
2,C调用java中的方法
在Android studio 2.2实现步骤如下,
1, 创建Java文件
1,1 新建工程
在Android studio中新建一个包名为com.android.example.ndk的NDK工程。在该路径下新建空的主工程文件,NDKActivity.java,内容如下,
package com.android.example.ndk;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class NDKActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ndk);
NDKJniCall jni = new NDKJniCall();
String CLanguagestring = jni.getCLanguageString();
Log.d("android ","CLanguagestring; " + CLanguagestring);
}
}
1.2 新建NDKJniCall.java
在工程的NDK\app\src\main\java\com\android\example\ndk目录下创建NDKJniCall.java文件,
主要包含native方法以及C的回调方法,内容如下,
package com.android.example.ndk;
import android.util.Log;
public class NDKJniCall {
static { //加载链接库文件
System.loadLibrary("NDKJniLib"); //defaultConfig.ndk.moduleName
}
public void getJavaName(String str){ // C的回调方法
Log.d("android ", "getJavaName: " + str);
}
public native String getCLanguageString();//native方法
}
2,创建 C文件
1,首先单击Android studio的Make Project生成class文件。
依次Build –>Make Project
生成的class文件路径为 NDK/app/build/intermediates/classes
2, 利用javah生成对应的 .h头文件
依次单击Android studio的 View -->Tool Windows –>Terminal
进入Terminal标签,在NDK> 后输入
cd app\build\intermediates\classes\debug
执行如下javah命令生成h文件。
javah -jni com.android.example.ndk.NDKJniCall
这样,目录NDK\app\build\intermediates\classes\debug 就有一个com_android_example_ndk_NDKJniCall.h 文件
3,在NDK\app\src\main目录下新建jni文件夹,将com_android_example_ndk_NDKJniCall.h 文件剪切到过来,该文件内容如下,
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_android_example_ndk_NDKJniCall */
#ifndef _Included_com_android_example_ndk_NDKJniCall
#define _Included_com_android_example_ndk_NDKJniCall
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_android_example_ndk_NDKJniCall
* Method: getCLanguageString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_android_example_ndk_NDKJniCall_getCLanguageString
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4,在NDK\app\src\main\jni文件夹新建JNINdkUtils.c,内容如下,
#include "com_android_example_ndk_NDKJniCall.h"
JNIEXPORT jstring JNICALL Java_com_android_example_ndk_NDKJniCall_getCLanguageString
(JNIEnv *env, jobject obj){
jclass clazz = (*env)->FindClass(env,"com/android/example/ndk/NDKJniCall");
jmethodID methodID = (*env)->GetMethodID(env,clazz, " getJavaName", "(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env,obj,methodID,(*env)->NewStringUTF(env," Java_C is successed"));
return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
}
3,环境配置
3.1 build.gradle 配置
打开NDK\app目录下的build.gradle文件,添加红色框中的内容。
3.2 配置android.mk文件
在NDK\app\src\main\jni文件夹新建Android.mk,内容如下,
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NDKJniLib
LOCAL_SRC_FILES := JNINdkUtils.c
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
到此Android studio下NDK JNI开发的代码编写和设置就OK了,
接下来就是编译工程运行就可以了。输入log如下,
01-01 08:36:52.715 D/android (12629): CLanguagestring; Android Studio NDK JNI C Language!
01-01 08:36:52.714 D/android (12629): getJavaName: Java_C is successed
小结:
1,利用工具和在系统中进行开发还是有很大不同的,工具无需注册JNI方法。
2,C/C++回调java方法都是利用反射机制。
3,C和C++使用JNIEnv还是不同的。