NDK 实现 Java 与 C/C++ 互调

NDK 实现 Java 与 C/C++ 互调

NDK 实现 Java 与 C/C++ 互调,实现int等类型的互相传递。

在上个项目中直接修改,步骤类似,为C多写一个回调方法,重点是C中如何获取该方法。

编写带 native 的 MainActivity

public class MainActivity extends Activity {

    static{
        System.loadLibrary("call");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            //c调用java后发送消息
            case 0:
                Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
            }
            super.handleMessage(msg);
        }
    };

    //按钮点击
    public void callJNI(View view) {
        String text = helloJNI();
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }

    //按钮点击
    public void callJINInt(View view) {
        callJNIInt(10);
    }

    // 由C回调
    private void callbackInt(int i){
        Message message = handler.obtainMessage();
        message.what = 0;
        message.obj = i;
        handler.sendMessage(message);
    }

    //本地方法
    private native String helloJNI();
    private native void callJNIInt(int i);

}

生成.h

在src目录下执行

$ javah -jni com.example.testjni.MainActivity

编写c

 * Signature: ()Ljava/lang/String;
#include "com_example_testjni_MainActivity.h"

/*
 * Class:     com_example_testjni_MainActivity
 * Method:    helloJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_testjni_MainActivity_helloJNI
  (JNIEnv * env, jobject obj){
    return (*env)->NewStringUTF(env, "text from c");
}

/*
 * Class:     com_example_testjni_MainActivity
 * Method:    callJNIInt
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_example_testjni_MainActivity_callJNIInt
  (JNIEnv * env, jobject obj, jint i){

    //找到java中的类
    jclass cls = (*env)->FindClass(env, "com/example/testjni/MainActivity");
    //再找类中的方法
    jmethodID mid = (*env)->GetMethodID(env, cls, "callbackInt", "(I)V");
    if (mid == NULL)
    {
//  LOGI("int error");
    return;
    }
    //打印接收到的数据
//  LOGI("from java int: %d",i);
    //回调java中的方法
    (*env)->CallVoidMethod(env, obj, mid ,i);
}

编写 Android.mk,生成 so

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := call
LOCAL_SRC_FILES := call.c

include $(BUILD_SHARED_LIBRARY)

cygwin ndk-build

Administrator@KakkPC /cygdrive/d/workspace_android/TestJNI/jni
$ ndk-build
[armeabi] Compile thumb  : call <= call.c
[armeabi] SharedLibrary  : libcall.so
[armeabi] Install        : libcall.so => libs/armeabi/libcall.so

刷新项目,生成libs/armeabi/libcall.so

走起,弹出个10…

下载 好吧,我在练习git而已…

你可能感兴趣的:(NDK 实现 Java 与 C/C++ 互调)