Jni API: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
JNIEnv,jobject 和 jclass 这三种基本类型
操作 API 都在 JNIEnv 中, JNIEnv 为 Java 与 C/C++ 通信桥梁
jobject:Java 层传递的对象 (普通 native 方法传递)
jclass:Java 层对应的 Class 类 (静态 native 方法传递)
native 普通方法与静态方法区别: Jni 传递参数是 jobject 和 jclass 区别
android studio ndk api 自动补齐
安装插件:
- Android NDK Support
- NDK WorkspaceManager Support
属性, 方法, 数组例子:
Java 层
- public class MainActivity extends AppCompatActivity {
- private static final String TAG = "MainActivity";
- // 测试属性
- public String strName ="test";
- // 排序数组
- private int[] array = {89,2,4,34,88,100,1};
- // Used to load the 'native-lib' library on application startup.
- static {
- System.loadLibrary("native-lib");
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // Example of a call to a native method
- TextView tv = (TextView) findViewById(R.id.sample_text);
- // 测试属性操作
- tv.setText(updateStringFromC());
- // 测试方法调用
- tv.setText(getJavaMethod());
- // 测试数组操作
- this.operateArraySort(array);
- for (int i = 0; i <array.length; i++){
- Log.e(TAG, "onCreate:" + array[i]);
- }
- // 异常处理 C++ 的异常 JAVA 是无法 try catch 的, 如果 jni 层出现了异常, 那么 Java 的代码调用中止
- try {
- exception();
- }catch (Exception e){
- Log.e(TAG, "onCreate:" + e.getMessage());
- }
- Log.e(TAG, "onCreate:" + "end");
- }
- // 测试方法
- public String getMethod(int a){
- return "method" + a;
- }
- /**
- * A native method that is implemented by the 'native-lib' native library,
- * which is packaged with this application.
- */
- public native String stringFromJNI();
- // 从 C 返回字符串
- public native String updateStringFromC();
- // 调用 Java 方法
- public native String getJavaMethod();
- // 对 array 数组进行排序操作
- public native void operateArraySort(int[] array);
- // 异常处理
- public native void exception();
- }
Jni 层:
- #include <jni.h>
- #include <string>
- #include "stdlib.h"
- //C C++ 混编
- int compare(const void* lhs, const void* rhs){
- return (*(int*)lhs - *(int*)rhs);
- }
- // 异常处理
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_home_adproj_androidndktest_MainActivity_exception(JNIEnv *env, jobject instance) {
- jclass _jclass = env->GetObjectClass(instance);
- jfieldID _jfieldID = env->GetFieldID(_jclass,"strName2","Ljava/lang/String;");//strName2 不存在有异常
- if(env->ExceptionCheck()){// 检测异常
- env->ExceptionClear();// 清除异常 不会使 Java 层崩溃
- // 抛异常给 Java 层
- jclass exceptionClass = env->FindClass("java/lang/IllegalArgumentException");
- env->ThrowNew(exceptionClass,"strName2 不存在");// 抛异常到 Java 层, Java 层进行捕获
- }
- }
- // 对 Java 数组进行操作
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_home_adproj_androidndktest_MainActivity_operateArraySort(JNIEnv *env, jobject instance,
- jintArray array_) {
- jint *arrays = env->GetIntArrayElements(array_, NULL);
- int _len = env->GetArrayLength(array_);// 获取数组长度
- //qsort(void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
- qsort(arrays,_len, sizeof(int),compare);// 数组排序
- env->ReleaseIntArrayElements(array_, arrays, 0);// 释放
- }
- // 调用 Java 层方法
- extern "C"
- JNIEXPORT jstring JNICALL
- Java_com_home_adproj_androidndktest_MainActivity_getJavaMethod(JNIEnv *env, jobject instance) {
- jclass _jclass =env->GetObjectClass(instance);
- //(jclass clazz, const char* name, const char* sig)
- jmethodID _jmethodID = env->GetMethodID(_jclass,"getMethod","(I)Ljava/lang/String;");//(参数类型)Ljava/lang/String 返回值类型
- jstring result = (jstring) env->CallObjectMethod(instance, _jmethodID,100);
- char* str = (char *) env->GetStringUTFChars(result, NULL);//string 转 char
- return env->NewStringUTF(str);
- }
- // 测试 Java 属性操作
- extern "C"
- JNIEXPORT jstring JNICALL
- Java_com_home_adproj_androidndktest_MainActivity_updateStringFromC(JNIEnv *env, jobject instance) {
- // TODO
- jclass _jclass = env->GetObjectClass(instance);
- //(jclass clazz, const char* name, const char* sig)
- //name: 属性名 sig: 属性类型
- jfieldID _jfieldID = env->GetFieldID(_jclass,"strName","Ljava/lang/String;");
- jstring _result = (jstring) env->GetObjectField(instance, _jfieldID);
- // 如何转化成 java string
- char* str = (char *) env->GetStringUTFChars(_result, NULL);
- char text[20] = "success";
- return env->NewStringUTF(strcat(str,text));
- }
- extern "C"
- JNIEXPORT jstring JNICALL
- Java_com_home_adproj_androidndktest_MainActivity_stringFromJNI(
- JNIEnv* env,
- jobject /* this */) {
- std::string hello = "Hello from C++";
- return env->NewStringUTF(hello.c_str());
- }
lldb:jni 调试工具
来源: http://www.bubuko.com/infodetail-2720387.html