Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android C代碼回調java方法,android回調

Android C代碼回調java方法,android回調

編輯:關於android開發

Android C代碼回調java方法,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”

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved