- 浏览: 517373 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
lin_kk:
最近正在学,请问LZ有源码事例吗,如果有能发一下我邮箱吗,万分 ...
使用libgdx及其中的box2d 2.1的注意事项 -
ahong520:
编译都通不过
ffmpeg对音频解码的一般步骤 -
辽东小小:
yajun_soft 写道XXX@XXX:~$ adb she ...
adb push的Permission denied -
cdtdx:
好文, 相当不错啊. 收了.
什么是app2sd,app2ext,data2ext?app移动到SD卡哪里去了? /mnt/asec /mnt/secure -
dickycat:
学习了,最近正在学这一块,年纪大了,学起来有点吃亏!
使用libgdx及其中的box2d 2.1的注意事项
1、 新建一个测试类TestProvider.java a) 该类提供了2个方法 b) 一个静态的方法,一个非静态的方法 2、 JNI中新建Provider.c a) 该文件中需要把Java中的类TestProvider映射到C中 b) 把TestProvider的两个方法映射到C中 c) 新建TestProvider 对象 d) 调用两个方法 3、 Android 上层 调用 JNI层 4、 JNI层调用C层 5、 C 层调用 Java 方法 1、界面设计如下: 老样子,很搓,不过实用,嘿嘿 代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。 2、 关键代码说明 C中定义映射的类、方法、对象 jclass TestProvider; jobject mTestProvider; jmethodID getTime; jmethodID sayHello; C 中映射 类 TestProvider = (*jniEnv)->FindClass(jniEnv,"com/duicky/TestProvider"); C中新建对象 jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, TestProvider,"<init>", "()V"); TestProvider mTestProvider = (*jniEnv)->NewObject(jniEnv, TestProvider,construction_id); C 中映射方法 静态: getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, "getTime","()Ljava/lang/String;"); 非静态: sayHello = (*jniEnv)->GetMethodID(jniEnv, TestProvider, "sayHello","(Ljava/lang/String;)V"); C 中调用 Java的 方法 静态: (*jniEnv)->CallStaticObjectMethod(jniEnv, TestProvider, getTime); 非静态: (*jniEnv)->CallVoidMethod(jniEnv, mTestProvider, sayHello,jstrMSG); 注意 GetXXXMethodID 和 CallXXXMethod 。 第一个XXX 表示的是映射方法的类型,如: 静态 跟非静态 第二个 XXX 表示 调用方法的返回值 ,如:Void,Object,等等。(调用静态方法的时候Call后面要加Static) 详细 映射方法 和 调用方法 请参考 JNI 文档 ,这个很重要 ! 3、 Java 上层 关键代码 TestProvider.Java 的两个方法 4、 Android.mk 文件 关键代码 老样子,不说了,你懂的。 如果不懂,嘎嘎,那就请点击Android.mk 文件 简介 5、 JNI文件夹下文件 Provider.h Provider.c CToJava.c 1、点击 “C调用java静态方法”按钮 C成功调用了Java中的getTime 方法,通过C方法打印出上层调用得到的时间,并且上层成功吐司出调用信息出来。 C成功调用了sayHello 方法, 并成功接收到 C 传递的参数,和 吐司出相对应的信息 a) C 映射java 方法时 对应的签名 getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, "getTime","()Ljava/lang/String;"); 故事情节还没发展这么快,下一章才会专门介绍下这个签名的使用 b)映射方法的时候需要区别静态和非静态GetStaticMethodID,GetMethodID c)调用的时候也需要区分CallStaticObjectMethod,CallVoidMethod 而且还需要区分返回值类型 有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢, 点击下载源码 C调用Java例子 本文出自 duicky 博客 , 转载请注明出处 http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html
1、主要流程
2、设计实现
package
com.duicky;
/**
*
*
* @author luxiaofeng <454162034@qq.com>
*
*/
public
class
TestProvider {
public
static
String getTime() {
LogUtils.printWithSystemOut(
"Call From C Java Static Method"
);
LogUtils.toastMessage(MainActivity.mContext,
"Call From C Java Static Method"
);
return
String.valueOf(System.currentTimeMillis());
}
public
void
sayHello(String msg) {
LogUtils.printWithSystemOut(
"Call From C Java Not Static Method :"
+ msg);
LogUtils.toastMessage(MainActivity.mContext,
"Call From C Java Not Static Method :"
+ msg);
}
}
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
LOCAL_MODULE := NDK_04
LOCAL_SRC_FILES := \
CToJava.c \
Provider.c
include $(BUILD_SHARED_LIBRARY)
#include <string.h>
#include <jni.h>
void
GetTime() ;
void
SayHello();
#include "Provider.h"
#include <android/log.h>
extern
JNIEnv* jniEnv;
jclass TestProvider;
jobject mTestProvider;
jmethodID getTime;
jmethodID sayHello;
int
GetProviderInstance(jclass obj_class);
/**
* 初始化 类、对象、方法
*/
int
InitProvider() {
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 1"
);
if
(jniEnv == NULL) {
return
0;
}
if
(TestProvider == NULL) {
TestProvider = (*jniEnv)->FindClass(jniEnv,
"com/duicky/TestProvider"
);
if
(TestProvider == NULL){
return
-1;
}
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 2 ok"
);
}
if
(mTestProvider == NULL) {
if
(GetProviderInstance(TestProvider) != 1) {
(*jniEnv)->DeleteLocalRef(jniEnv, TestProvider);
return
-1;
}
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 3 ok"
);
}
if
(getTime == NULL) {
getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider,
"getTime"
,
"()Ljava/lang/String;"
);
if
(getTime == NULL) {
(*jniEnv)->DeleteLocalRef(jniEnv, TestProvider);
(*jniEnv)->DeleteLocalRef(jniEnv, mTestProvider);
return
-2;
}
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 4 ok"
);
}
if
(sayHello == NULL) {
sayHello = (*jniEnv)->GetMethodID(jniEnv, TestProvider,
"sayHello"
,
"(Ljava/lang/String;)V"
);
if
(sayHello == NULL) {
(*jniEnv)->DeleteLocalRef(jniEnv, TestProvider);
(*jniEnv)->DeleteLocalRef(jniEnv, mTestProvider);
(*jniEnv)->DeleteLocalRef(jniEnv, getTime);
return
-3;
}
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 5 ok"
);
}
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"InitProvider Begin 6"
);
return
1;
}
int
GetProviderInstance(jclass obj_class) {
if
(obj_class == NULL) {
return
0;
}
jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, obj_class,
"<init>"
,
"()V"
);
if
(construction_id == 0) {
return
-1;
}
mTestProvider = (*jniEnv)->NewObject(jniEnv, obj_class,
construction_id);
if
(mTestProvider == NULL) {
return
-2;
}
return
1;
}
/**
* 获取时间 ---- 调用 Java 方法
*/
void
GetTime() {
if
(TestProvider == NULL || getTime == NULL) {
int
result = InitProvider();
if
(result != 1) {
return
;
}
}
jstring jstr = NULL;
char
* cstr = NULL;
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"GetTime Begin"
);
jstr = (*jniEnv)->CallStaticObjectMethod(jniEnv, TestProvider, getTime);
cstr = (
char
*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"Success Get Time from Java , Value = %s"
,cstr );
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"GetTime End"
);
(*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr);
(*jniEnv)->DeleteLocalRef(jniEnv, jstr);
}
/**
* SayHello ---- 调用 Java 方法
*/
void
SayHello() {
if
(TestProvider == NULL || mTestProvider == NULL || sayHello == NULL) {
int
result = InitProvider() ;
if
(result != 1) {
return
;
}
}
jstring jstrMSG = NULL;
jstrMSG =(*jniEnv)->NewStringUTF(jniEnv,
"Hi,I'm From C"
);
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"SayHello Begin"
);
(*jniEnv)->CallVoidMethod(jniEnv, mTestProvider, sayHello,jstrMSG);
__android_log_print(ANDROID_LOG_INFO,
"JNIMsg"
,
"SayHello End"
);
(*jniEnv)->DeleteLocalRef(jniEnv, jstrMSG);
}
#include <string.h>
#include <android/log.h>
#include <jni.h>
#include "Provider.h"
JNIEnv* jniEnv;
/**
* Java 中 声明的native getTime 方法的实现
*/
void
Java_com_duicky_MainActivity_getTime(JNIEnv* env, jobject thiz)
{
if
(jniEnv == NULL) {
jniEnv = env;
}
GetTime();
}
/**
* Java 中 声明的native sayHello 方法的实现
*/
void
Java_com_duicky_MainActivity_sayHello(JNIEnv* env, jobject thiz)
{
if
(jniEnv == NULL) {
jniEnv = env;
}
SayHello();
}
3、运行效果
2、点击 “C调用java非静态方法”按钮
4、C调用Java注意点
发表评论
-
编译XT720 gingerbread
2013-05-04 11:18 867在android根目录下执行". build/env ... -
编译mx 内核成功
2013-03-18 17:48 875转 : http://hi.baidu.com/_xi ... -
ubuntu下面找不到ZTE V880设备
2012-12-06 16:22 839两种方法:第一种方法是你连上你的手机,重启电脑,再adb de ... -
Android中解决图像解码导致的OOM问题
2012-10-01 18:41 819http://7dot9.com/2011/08/androi ... -
编译Android下纯C的静态程序,undefined reference to raise
2012-07-08 23:28 2375尝试在Android下编译纯C的静态程序,执行gcc -v - ... -
开发Android下纯C程序时,打开时提示not found
2012-07-08 20:09 1381这个问题烦了我一天了..郁闷.本人想试验一下使用ndk里面的t ... -
NDK报错:make: *** 没有规则可以创建“obj/local/armeabi/objs/a/a.o”需要的目标“/a.c”。 停止。
2012-07-05 21:02 2179android开发用ndk编译so库时,有时直接从别的地 ... -
adb push的Permission denied
2012-05-30 17:19 3662遇到的问题是 zhanglanyun@zhanglan ... -
adb pull失败问题解决方法
2012-05-30 17:03 2187问题:使用adb pull命令从android系统中读取文件失 ... -
关于app2sd、a2sd、data2sd、a2sd+的区别的解释
2012-05-17 11:47 1067因为看到很多机友对这个概念不理解。首先解释一下这些缩写,全部的 ... -
什么是app2sd,app2ext,data2ext?app移动到SD卡哪里去了? /mnt/asec /mnt/secure
2012-05-17 10:56 3373Google Android手机的软件为了安全性和稳定性 ... -
android 如何自定义ProgressBar
2012-04-22 15:39 1915原文:http://blog.sina.com.cn/s/bl ... -
修改MAC,没有nvs_map.bin时该怎么做
2012-04-10 16:53 1826Basically: nvs_map.bin is what ... -
Android Activity LaunchMode 验证
2012-03-31 11:23 915在Android中,每个Activity有4种LaunchMo ... -
Android改变MAC地址
2012-03-30 13:42 21751.Find out your original MAC ad ... -
使用ndk或linux下独立交叉编译(ffmpeg)
2012-03-18 21:48 23051、ndk 编译程序 在NDK的apps目录下创建he ... -
android-ndk-r7 编译 ffmpeg-0.10
2012-03-18 21:46 4603看了这篇文章 http://blog.sina.com ... -
android2.3 MODIFY_PHONE_STATE
2012-02-27 22:14 3065一直被一些莫名其妙的电话骚扰,而且只响两声就断了,一直 ... -
Androidmanifest.xml里的<uses-feature>
2011-12-27 17:10 1366如果你是一个Android用户,而且你有一个老旧的安装有and ... -
android程序中取得root
2011-10-25 19:42 1062public static boolean runRootCo ...
相关推荐
使用`GetMethodId`函数获取Java方法的ID,这个ID是JNI调用Java方法的关键。函数接受三个参数:JNIEnv指针,类的引用(`jclass`),以及方法名和方法签名的字符串。方法签名描述了方法的参数类型和返回类型,如`"()V...
在Linux环境中,C语言可以通过Java Native Interface (JNI) 来调用Java的静态和非静态方法,实现两者之间的交互。JNI是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互,使得C/C++程序员可以编写...
JNI调用Java静态属性的步骤大致如下: 1. 获取Java类对象:和非静态属性类似,使用`GetObjectClass`函数获取目标Java对象所属的类对象。 2. 获取静态字段ID:使用`GetStaticFieldID`函数根据字段名和类型签名获取...
以上步骤详细介绍了如何在Delphi 7中通过JNI调用Java接口,实现两者的交互。这为混合编程提供了可能,允许开发者充分利用两种语言的优点,如Delphi的快速Windows开发和Java的跨平台能力。在实际应用中,可能还需要...
在上述示例中,我们看到`JniTest`类的实例方法和静态方法都被调用了。例如,`jni.PrintHello()`将调用C++中的`Java_JniTest_PrintHello()`,`jni.PrintArray(arr)`则会调用`Java_JniTest_TestArray()`,并将数组`arr...
例如,对于一个Java类的实例方法,非静态头文件会定义一个接受`JNIEnv*`和` jobject`参数的函数,`JNIEnv`指针用于调用JNI函数,`jobject`则是对Java对象的引用。 2. **静态头文件(-static)**: 使用`-static`...
本教程将详细介绍如何在Android中使用JNI实现C语言回调Java的方法,包括有参无参、有无返回值以及静态非静态函数的不同情况。 1. **JNI基础概念** JNI是Java平台的标准组成部分,它提供了一套接口,使得Java代码...
这个头文件包含了Java方法的C++声明,使得C++代码能够理解并调用Java方法。 2. **实现JNI函数**:在C++中,我们需要实现这些声明的函数,这些函数将在Android运行时环境中被Java层调用。 3. **注册JNI函数**:在...
通过上述介绍,我们可以了解到如何在C++环境中通过JNI调用Java代码来实现用户身份验证和权限管理的功能。这种跨语言调用的方法不仅可以提高系统的灵活性,还能充分利用两种语言的优势。对于需要在C++环境中集成Java...
总的来说,通过JNI,开发者可以在C/C++代码中无缝地调用Java方法,实现两者的深度融合。然而,这种方式增加了程序的复杂性,同时也可能引入潜在的内存泄漏和线程安全问题,因此在使用时需要谨慎并做好充分的测试。
在Java中,如果一个方法被声明为`native`,那么这个方法的实现并不在Java代码中,而是通过JNI调用其他语言(如C/C++)的代码来实现。本教程将详细介绍如何在Linux环境下使用JNI调用C/C++动态库。 1. **创建Java类**...
JNI接口定义了一组函数和数据类型,使得Java代码能够声明并调用本地方法(即非Java代码),同时本地方法也能调用Java代码。这通常涉及到以下步骤: 1. **编写Java代码**:在Java类中声明native方法,该方法没有具体...
JNI的主要职责是提供一套API,使Java代码能够调用非Java语言(如C/C++)编写的本地方法,同时也能让本地代码反向调用Java方法。通过JNI,开发人员可以创建、检查和更新Java对象(包括数组和字符串),调用Java方法,...
对于非静态方法,需要获取`thisObj`指向的对象的类并找到对应的方法ID。 ### 6. 链接与编译 将C/C++代码编译为动态链接库(如`libmylibrary.so`)。在Android项目中,这通常通过Android.mk或CMakeLists.txt文件...
《JNI调用C++的应用实例》 JNI,全称Java Native Interface,是Java平台中用于实现Java代码与其他语言(如C/C++)交互的关键技术。自Java 1.1起,JNI已成为Java平台的标准组成部分,它允许Java应用程序利用本地代码...
JNI提供了多种函数来调用Java的方法,包括静态方法和实例方法。例如,`CallVoidMethod`用于调用返回值为void的方法,`GetObjectField`用于获取对象的字段值。 5. **本地方法的注册** 在C/C++代码中,需要通过`...
例如,调用非静态方法: ```c++ jmethodID method = env->GetMethodID(clazz, "callJavaMethod", "()V"); env->CallVoidMethod(obj, method); ``` 调用静态方法: ```c++ jmethodID staticMethod = env->...
- 调用非静态方法:`void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID mid, ...)`。 - 以上函数有对应返回值的版本,例如`CallIntMethod`,`CallLongMethod`等,适用于返回不同类型的方法。 6. **参数和...
8. **调用Java方法**:本地代码可以通过JNI调用Java方法,包括静态方法、实例方法和构造方法。这涉及到`CallStaticVoidMethod`、`CallVoidMethod`、`NewObject`等函数。 9. **访问Java对象**:JNI允许本地代码访问...