1
2
3
4
5
6
7
8
9
10
11
|
static
{
System.loadLibrary(
"xx"
);
//xx是Android.mk文件中LOCAL_MODULE 的字段
}
//必须和ndk中的方法名一样
public
native
String getString();
//onclick方法
public
void
click(View v){
String str = getString();
System.out.println(
"调用JNI中的方法:"
+str);
}
|
1
2
3
4
5
6
7
8
9
10
11
|
#include <jni.h>
#include<string.h>
/**
* extern "C" 是必须加的,经测试不加的话方法调用不成功,也没找到答案,有知道为什么的请* 告知,方法名称必须按照JNI的规范来Java_包名_类名_方法名,都必须以'_'隔开。
*/
extern
"C"
jstring Java_com_test_ndk_A_getString(JNIEnv* env,jobject thiz){
jstring str ;
//在C中的是以(*env)->调用的,网上大部分的博客文档也是这种情况。
str = env->newStringUTF(
"hello world"
);
//不能使用中文,不然会报错。
return
str;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
static
{
System.loadLibrary(
"ndk"
);
}
public
native
void
loadJavaMethod();
public
void
f1(){
String str ;
str =
"hello world from java"
;
System.out.println(str);
}
public
String f2(){
String str ;
str =
"f2: hello world from java"
;
System.out.println(str);
return
str;
}
public
void
f3(String str,
int
i){
System.out.println(
"f3 内容为:"
+str+
",数字为:"
+i);
}
|
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
|
#include <jni.h>
#include<string.h>
extern
"C"
void
Java_com_test_ndk_B_loadJavaMethod(JNIEnv *env,jobject thiz){
//调用无参无返回值的方法
jclass cls = env->GetObjectClass(thiz);
//GetMethodID("jclass对象","方法名","方法参数")
jmethodID mID = env->GetMethodID(cls,
"f1"
,
"()V"
);
if
(mID != NULL){
env->CallVoidMethod(thiz,mID);
}
//调用有参无返回值得方法
//参数类型除了基本数据类型外,其他的都需要按照这样的格式
//L包名/类名; 包名用/分割,必须以;结束
//详情请参考这篇文章
jclass cls = env->GetObjectClass(thiz);
jmethodID mID = env->GetMethodID(cls,
"f3"
,
"(Ljava/lang/String;I)V"
);
jstring content = env->NewStringUTF(
"hehe"
);
jint i =
10
;
if
(mID != NULL){
env->CallVoidMethod(thiz,mID,content,i);
}
//调用有返回值无参的方法
jclass cls = env->GetObjectClass(thiz);
jmethodID mID = env->GetMethodID(cls,
"f2"
,
"()Ljava/lang/String;"
);
if
(mID != NULL){
env->CallObjectMethod(thiz,mID);
}
//调用其他类中的方法假设有一个Student类,如果要使用Student类中的内部类A,格式为
//com/test/ndk/Student$A
jclass stu = env->FindClass(
"com/test/ndk/Student"
);
//实例化无参构造方法
jobject stuObj = env->NewObject(stu,env->GetMethodID(stu,
"<init>"
,
"()V"
));
jmethodID getNameId = env->GetMethodID(stu,
"getName"
,
"()V"
);
if
(getNameId !=NULL){
env->CallVoidMethod(stuObj,getNameId);
}
}
|
1
2
3
4
5
6
7
8
|
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libthird
LOCAL_SRC_FILES := libthird.so
include $(PREBUILT_SHARED_LIBRARY)
|
1
2
3
4
5
6
7
8
9
10
11
12
|
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndk
LOCAL_SRC_FILES := ndk.cpp
#名称和第三方mk中LOCAL_MODULE定义的名称一样
LOCAL_SHARED_LIBRARIES := libthird
include $(BUILD_SHARED_LIBRARY)
#添加路径
include $(LOCAL_PATH)/prebuilt/Android.mk
|
1
2
3
4
|
//extern "C"在第三方的包中的方法也必须添加,测试时,如果不添加方法调用不成功,但这个是不能限//制到第三方的,有待解决
extern
"C"
int
f1(){
return
101
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <jni.h>
#include <dlfcn.h>
#include <fcntl.h>
void
*filehandle = NULL;
jstring (*f1)() =NULL;
extern
"C"
jint Java_com_test_ndk_classA_f1(JNIEnv * env,jobject thiz){
jint i ;
filehandle = dlopen(
"/data/data/com.fly.ndk2/lib/libndk.so"
, RTLD_LAZY);
if
(filehandle){
f1 = (
int
(*)())dlsym(filehandle,
"f1"
);
}
if
(f1){
i = f1();
dlclose(filehandle);
filehandle = NULL;
}
return
i;
}
|