我知道这是旧的,但人们仍然可以通过搜索找到它。
这里是完整的解决方案,如何从java调用C代码,以及从jni c代码回调java代码:
在你的项目 jni 目录中创建 Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ALLOW_UNDEFINED_SYMBOLS=false
LOCAL_MODULE := testjni
LOCAL_SRC_FILES := testjni.c
LOCAL_LDLIBS := -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
在你的项目 jni 目录中创建 Application.mk
APP_ABI := armeabi-v7a
APP_PLATFORM := android-8
在你的项目 jni 目录中创建 testjni.c
#include <jni.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"TAG",__VA_ARGS__)
JavaVM *myVm;
static void *android_gui = NULL;
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
// Keep a reference on the Java VM.
myVm = vm;
LOGD("JNI interface loaded.");
return JNI_VERSION_1_2;
}
void jni_setDataEnv(JNIEnv *p_env, int width, int height)
{
if (android_gui == NULL)
return;
jclass cls = (*p_env)->GetObjectClass (p_env, android_gui);
jmethodID methodId = (*p_env)->GetMethodID (p_env, cls, "setData", "(II)V");
//add or delete II's depinding your number or variable passsed
(*p_env)->CallVoidMethod (p_env, android_gui, methodId, width, height);
(*p_env)->DeleteLocalRef(p_env, cls);
}
void jni_setData(int width, int height)
{
JNIEnv *p_env;
(*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
jni_setDataEnv(p_env, width, height);
int check = (*myVm)->GetEnv(myVm, (void *) &p_env, JNI_VERSION_1_2);
LOGD(" Detach destructor = %d", check);
if (check != JNI_EDETACHED)
{
int detach = (*myVm)->DetachCurrentThread (myVm);
LOGD("Detach result ==: %d", detach);
}
}
//change this to your package
JNIEXPORT void JNICALL Java_com_example_test_LibTest_initM(JNIEnv *env, jobject thiz, jobject gui)
{
android_gui = (*env)->NewGlobalRef(env, gui);
}
//when you need , in your c code call jni_setData(100.200 ) and
//MainActivity method , setData() will receive this values
void *call_from_thread()
{
jni_setData(1,2);
return NULL;
}
JNIEXPORT void JNICALL Java_com_example_test_LibTest_test(JNIEnv *env, jobject thiz)
{
pthread_t t;
//do hard work in a thread
pthread_create(&t, NULL, call_from_thread, NULL);
}
在 jni 文件夹中运行 ndk-build 编译库 libtest.so
在您的 java android 项目 src 中创建:MyInterface.java
package com.example.test;
public interface MyInterface
{
void setData(int width, int height);
}
创建LibTest.java //用于从java向C代码发送数据
package com.example.test;
public class LibTest
{
static
{
System.loadLibrary("testjni");
}
private static LibTest sInstance;
public static LibTest getInstance()
{
synchronized (LibTest.class)
{
if (sInstance == null)
{
/* First call */
sInstance = new LibTest();
}
}
return sInstance;
}
public native void initM( MyInterface myinterface );
public native void test();
}
创建 MainActivity.java
package com.example.test;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity implements MyInterface
{
int mHeight;
int mWidth;
LibTest libtest;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
libtest = LibTest.getInstance();
libtest.initM( MainActivity.this );
//tell jni to send us some data
//we receive data in 'setData(int width, int height)' method
libtest.test();
}
@Override
public void setData(int width, int height)
{
/// Here you receive data from C code
//We can store the values C send to Java so we use latter
mHeight = height;
mWidth = width;
Log.d("TAG" ,"GOT SOME DATA FROM C CODE" + mHeight + " " + mWidth );
}
}