android使用c通过jni回调java
来源:互联网 发布:网络服务商有哪些 编辑:程序博客网 时间:2024/06/02 23:19
很多场合都有这样的需求,由于以前都是java调用c的接口,没有做过回调,今天花了大半天时间把这个流程跑通了,记录一下,以备后用。这里发句牢骚,那些网上分享出来的代码,请问你们确实是能正常工作吗?还有查来查去都是那几份,大家转载精神可嘉啊
jni相关头文件代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_example_ndktest_CallbackTest */
#ifndef _Included_com_example_ndktest_CallbackTest
#define _Included_com_example_ndktest_CallbackTest
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* Class: com_example_ndktest_CallbackTest
* Method: start
* Signature: ()V
*/
JNIEXPORT
void
JNICALL Java_com_example_ndktest_CallbackTest_start
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
具体实现代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<span></span> #include<stdlib.h>
#include<pthread.h>
#include<jni.h>
#include<android/log.h>
#include "com_example_ndktest_CallbackTest.h"
#define LOG_TAG "jni"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
jmethodID mid;
jclass objclass;
jobject mobj;
pthread_t
thread
;
JavaVM *m_vm;
//初始化的时候会调进来一次,在这个方法里持有jvm的引用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void
*reserved){
m_vm=vm;
JNIEnv* env = NULL;
jint result = -1;
if
(m_vm){
LOGD(
"m_vm init success"
);
}
else
{
LOGD(
"m_vm init failed"
);
}
if
((*vm)->GetEnv(vm, (
void
**)&env, JNI_VERSION_1_4) != JNI_OK){
return
result;
}
return
JNI_VERSION_1_4;
}
JNIEnv* getJNIEnv(
int
* needsDetach){
JNIEnv* env = NULL;
jint result = -1;
if
((*m_vm)->GetEnv(m_vm, (
void
**) &env, JNI_VERSION_1_4) != JNI_OK){
int
status = (*m_vm)->AttachCurrentThread(m_vm, &env, 0);
if
(status < 0){
LOGD(
"failed to attach current thread"
);
return
NULL;
}
*needsDetach = 1;
}
LOGD(
"GetEnv Success"
);
return
env;
}
void
*thread_run(){
LOGD(
"thread start"
);
int
needsDetach;
JNIEnv *evn=getJNIEnv(&needsDetach);
LOGD(
"start noop callback"
);
int
i;
for
(i = 0; i < 100; i++){
jstring jstr = (*evn) -> NewStringUTF(evn,
"I am Fengfei"
);
LOGD(
"invoke callback"
);
(*evn)->CallVoidMethod(evn, mobj, mid, jstr);
jthrowable exception = (*evn)->ExceptionOccurred(evn);
if
(exception) {
(*evn)->ExceptionDescribe(evn);
}
sleep(2);
}
if
(needsDetach)
(*m_vm)->DetachCurrentThread(m_vm);
}
JNIEXPORT
void
JNICALL Java_com_example_ndktest_CallbackTest_start(JNIEnv *evn, jobject object){
LOGD(
"call start"
);
//在子线程中不能这样用
//jclass tclass = (*evn)->FindClass(evn, "com/example/ndktest/CallbackTest");
//这种写法可以用在子线程中
objclass=(*evn)->GetObjectClass(evn, object);
mid = (*evn)->GetMethodID(evn, objclass,
"callback"
,
"(Ljava/lang/String;)V"
);
//JNI 函数参数中 jobject 或者它的子类,其参数都是 local reference。Local reference 只在这个 JNI函数中有效,JNI函数返回后,引用的对象就被释放,它的生命周期就结束了。若要留着日后使用,则需根据这个 local reference 创建 global reference。Global reference 不会被系统自动释放,它仅当被程序明确调用 DeleteGlobalReference 时才被回收。(JNI多线程机制)
mobj=(*evn)->NewGlobalRef(evn, object);
pthread_create(&
thread
, NULL, thread_run, NULL);
}
java代码(具体怎么生成.so,参看android ndk使用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package
com.example.ndktest;
public
class
CallbackTest {
static
{
System.loadLibrary(
"callback"
);
}
public
native
void
start();
public
void
callback(String str){
System.out.println(str);
}
}
0 0
- android使用c通过jni回调java
- Android C 通过JNI 调用JAVA
- Android JNI 通过C/C++调用JAVA方法
- 使用Qt / C + +通过JNI调用Java代码
- Java使用JNI调用C/C++(windows和android平台)
- java通过jni调用C程序
- Java通过JNI调用C/C++函数
- JAVA通过JNI调用C函数Demo
- java通过jni调用c库
- Java通过JNI调用C语言
- Java 通过 JNI 调用 C/C++ 类库
- Java通过jni调用c语言方法
- JNI小程序:Java通过JNI调用C程序
- Android使用JNI实现Java与C之间传递数据
- Android使用JNI实现Java与C之间传递数据
- Android使用JNI实现Java与C之间传递数据
- Android使用JNI实现Java与C之间传递数据
- Android使用JNI实现Java与C之间传递数据
- 两个对象之间的比较,实现接口IComparable
- 文本换行显示
- git-常用命令
- c++,对txt文件进行读取显示
- Programming Exercise 6:Support Vector Machines
- android使用c通过jni回调java
- 搭建Eclipse、Resin Web开发环境
- java 反射机制读取属性值
- PIL安装使用
- 今日BBC
- mvn基本命令
- iOS程序员必备常用工具
- 安装和测试Kafka(转)
- LINUX 手动建立SWAP文件及删除