編輯:關於android開發
本文將講述下列三種C代碼回調java方法
1、c代碼回調java空方法
2、c代碼回調java int類型參數方法
3、c代碼回調javaString類型參數方法
方法都差不多,先看c代碼回調java空方法,其他兩種類似:
① 找到字節碼對象
//jclass (*FindClass)(JNIEnv*, const char*);
//第二個參數 要回調的java方法所在的類的路徑 "com/itheima/callbackjava/JNI"
② 通過字節碼對象找到方法對象
//jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
第二個參數 字節碼對象 第三個參數 要反射調用的java方法名 第四個參數 要反射調用的java方法簽名
javap -s 要獲取方法簽名的類的全類名 項目/bin/classes 運行javap

③ 通過字節碼創建 java對象(可選) 如果本地方法和要回調的java方法在同一個類裡可以直接用 jni傳過來的java對象 調用創建的Method
jobject obj =(*env)->AllocObject(env,claz);
當回調的方法跟本地方法不在一個類裡 需要通過剛創建的字節碼對象手動創建一個java對象
再通過這個對象來回調java的方法
需要注意的是 如果創建的是一個activity對象 回調的方法還包含上下文 這個方法行不通!!!回報空指針異常
④ 反射調用java方法
//void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
第二個參數 調用java方法的對象 第三個參數 要調用的jmethodID對象 可選的參數 調用方法時接收的參數
接下來實戰項目實現
新建項目,布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="callbackvoid"
android:text="回調null方法" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="callbackint"
android:text="回調int參數方法" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="callbackString"
android:text="回調String參數方法" />
</LinearLayout>
新建JNI.java
package com.wuyudong.callbackjava;
public class JNI {
static{
System.loadLibrary("callback");
}
public native void callbackvoidmethod();
public native void callbackintmethod();
public native void callbackStringmethod();
// C調用java空方法
public void helloFromJava() {
System.out.println("hello from java");
}
// C調用Java中的帶兩個int參數的方法
public int add(int x, int y) {
return x + y;
}
// C調用java中參數為String的方法
public void printString(String s) {
System.out.println(s);
}
}
MainActivity.java
package com.wuyudong.callbackjava;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
JNI jni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jni = new JNI();
}
public void callbackvoid(View v) {
jni.callbackvoidmethod();
}
public void callbackint(View v) {
jni.callbackintmethod();
}
public void callbackString(View v) {
jni.callbackStringmethod();
}
}
callback.c
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackvoidmethod(
JNIEnv * env, jobject clazz) {
//1、獲取字節碼對象 jclass (*FindClass)(JNIEnv*, const char*);
jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
//2、獲取Method對象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodID = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
//3、通過字節碼對象創建一個Object(即是clazz)
//4、通過對象調用方法
(*env)->CallVoidMethod(env, clazz, methodID);
}
JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackintmethod(
JNIEnv * env, jobject clazz) {
//1、獲取字節碼對象 jclass (*FindClass)(JNIEnv*, const char*);
jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
//2、獲取Method對象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodID = (*env)->GetMethodID(env, claz, "add", "(II)I");
//3、通過字節碼對象創建一個Object(即是clazz)
//4、通過對象調用方法
int result = (*env)->CallIntMethod(env, clazz, methodID, 3, 5);
LOGD("result = %d", result);
}
JNIEXPORT void JNICALL Java_com_wuyudong_callbackjava_JNI_callbackStringmethod(
JNIEnv * env, jobject clazz) {
//1、獲取字節碼對象 jclass (*FindClass)(JNIEnv*, const char*);
jclass claz = (*env)->FindClass(env, "com/wuyudong/callbackjava/JNI");
//2、獲取Method對象 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodID = (*env)->GetMethodID(env, claz, "printString",
"(Ljava/lang/String;)V");
//3、通過字節碼對象創建一個Object(即是clazz)
//4、通過對象調用方法
//char* str = "hello from c!";
jstring result = (*env)->NewStringUTF(env, "hello from c");
(*env)->CallVoidMethod(env, clazz, methodID, result);
}
獲取更多C語言與算法相關知識,關注公眾號:“csuanfa”

安卓四大組件之內容提供者,安卓四大提供者
安卓四大組件之內容提供者,安卓四大提供者 內容提供者ContentProvider,是A
Android 手機衛士17--緩存清理,android17--
Android 手機衛士17--緩存清理,android17-- 清理單個應用緩存 通過反射調用方法 需要權限:android.permissi
Android中事件的分發機制
Android中事件的分發機制 Android事件構成 在Android中,事件主要包括點按、長按、拖拽、滑動等,點按又包括單擊和雙擊,另外還包括單指操
Android應用開發教程之十四:獲取日志信息
分享一個在程序中監聽Log信息的很實用的例子。 為什麼說它實用?原因是Android的開發廠商各種修改之後手機和手機之間以後存在很多差異。比如說魅
如何處理 android 方法總數超過 65536 . the number of method references in a .dex file exceed 64k,android.dex
如何處理 android 方法總數超過 65536 . the numb
Android種使用Notification實現通知管理以及自定義通知欄(Notification示例四),自定義notification
Android種使用Notification實現通知管理以及自定義通知欄