1、编写native方法(java2c)和非native方法(c2java):

package com.example.provider;

public class CallbackJava {

    // C调用java空方法
public void helloFromJava() { System.out.println("hello from java");
} // C调用java中的带两个int参数的方法
public int Add(int x, int y) {
int result = x + y;
System.out.println("java result=" + result);
return result;
} // C调用java中参数为string的方法
public void printString(String s) {
System.out.println("java " + s);
} //静态方法
public static void printStaticStr(String s) {
System.out.println("java static-> " + s);
} // 让c代码调用对应的java代码
public native void callHelloFromJava(); public native void callAdd(); public native void callPrintString(); // 调用一个静态的c代码
public native void callPrintStaticStr();
}

2、通过javah命令生成签名,通过javap命令生产native方法签名:

  

3、c代码

FindClass:找到java中的类文件
GetMethodID:根据类和方法签名找到要调用的方法。
#include <stdio.h>
#include <jni.h>
#include <malloc.h>
#include "com_example_provider_CallbackJava.h";
#include "com_example_jni_MainActivity.h"; #include <android/log.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) jmethodID getMethodId(JNIEnv * env, char* methodname, char* signname) {
jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");
if (jclazz == ) {
LOGD("class not find ");
return;
}
//2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名
jmethodID methodid = (*env)->GetMethodID(env, jclazz, methodname, signname);
if (methodid == ) {
LOGD("method not find ");
return;
}
return methodid;
} JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callHelloFromJava
(JNIEnv * env, jobject obj) {
//1、 找java中的class文件
//第二个参数是类名的(包名)
jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");
if(jclazz==) {
LOGD("class not find ");
return;
}
//2、找class中方法的id,第三个参数方法名称,第四个参数该方法对应的签名
jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");
if(methodid==) {
LOGD("helloFromJava method not find ");
return;
}
//3、调用方法
//void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env,obj,methodid);
} JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callAdd
(JNIEnv *env, jobject obj) {
jmethodID mid = getMethodId(env,"Add","(II)I");
int result = (*env)->CallIntMethod(env, obj, mid,,);
LOGD("c to java add: d%",result);
} JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintString
(JNIEnv *env, jobject obj) {
LOGD("c to java callPrintString start ");
jmethodID mid = getMethodId(env,"printString","(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env, obj, mid,(*env)->NewStringUTF(env," call printString finish"));
LOGD("c to java callPrintString finish ");
} JNIEXPORT void JNICALL Java_com_example_provider_CallbackJava_callPrintStaticStr
(JNIEnv *env, jobject obj) {
jclass jclazz = (*env)->FindClass(env, "com/example/provider/CallbackJava");
if (jclazz == ) {
LOGD("class not find ");
return;
}
//静态方法调用GetStaticMethodID 和 CallStaticXXXMethod
jmethodID methodid = (*env)->GetStaticMethodID(env, jclazz, "printStaticStr", "(Ljava/lang/String;)V");
if (methodid == ) {
LOGD("printStaticStr method not find ");
return;
}
(*env)->CallStaticVoidMethod(env, jclazz, methodid,(*env)->NewStringUTF(env,"static hello java")); } JNIEXPORT void JNICALL Java_com_example_jni_MainActivity_callProvider
(JNIEnv *env, jobject obj){
jclass jclazz = (*env)->FindClass(env,"com/example/provider/CallbackJava");
if(jclazz==) {
LOGD("class not find ");
return;
}
jmethodID methodid = (*env)->GetMethodID(env, jclazz,"helloFromJava","()V");
if(methodid==) {
LOGD("helloFromJava method not find ");
return;
}
//创建一个CallbackJava对象
jobject jobj =(*env)->AllocObject(env, jclazz);
(*env)->CallVoidMethod(env,jobj,methodid); }

4、编译多个c文件可以用空格分开

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=Hello
#LOCAL_SRC_FILES :=Hello.c
LOCAL_SRC_FILES :=CallbackJava.c Hello.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)

参考http://www.open-open.com/lib/view/open1359700820369.html

 

Android学习笔记_JNI_c调用java代码的更多相关文章

  1. 六、Android学习笔记_JNI_c调用java代码

    1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // ...

  2. JNI学习笔记_C调用Java

    一.笔记 1.C调用Java中的方法,参考jni.pdf pg97可以参考博文:http://blog.csdn.net/lhzjj/article/details/26470999步骤: a. 创建 ...

  3. android Webview 实现js调用java代码实现Activity跳转

    今天有了一个需求,在android里webview加载的html页面,要求点击html页面的按钮实现Activity的跳转. 咱是是菜鸟,webview的接触不多,于是就和度娘来了次亲密接触.在其中也 ...

  4. Android学习笔记(9):使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...

  5. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  6. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  7. 【转】 Pro Android学习笔记(七七):服务(2):Local Service

    目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...

  8. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  9. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

随机推荐

  1. CF 305A——Strange Addition——————【暴力加技巧】

    A. Strange Addition time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. NBUT 1107——盒子游戏——————【博弈类】

    盒子游戏 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format: Submit Status Practice NBUT 110 ...

  3. mysql 查两个表相同的值

    比如一个数据库 表A和表B 都有一个username字段, 现查出与表A中username值相同的表B的username和password数据 select B.username,B.password ...

  4. C# 调用者信息获取

    做日志组件时,常常会记录调用者信息,通常都是通过反射来获取相应信息.不过.Net 4.5引入了三个新的特性,即CallerFilePathAttribute,CallerLineNumberAttri ...

  5. Git for Android Studio 学习笔记

    http://learngitbranching.js.org/ 一个特别好的git学习教程 创建一个project,然后导入github

  6. Spring课程 Spring入门篇 4-4 Spring bean装配(下)之Autowired注解说明3 多选一 qualifier

    本节主要讲述以下内容: 1 简述 2 代码演练 2.1 注解qualifier运用 1 简述 1.1 何种情况使用qualifier注解? a 按类型自动装配多个bean实例,可以用@qualifie ...

  7. 2、Dubbo源码解析--服务发布原理(Netty服务暴露)

    一.服务发布 - 原理: 首先看Dubbo日志,截取重要部分: 1)暴露本地服务 Export dubbo service com.alibaba.dubbo.demo.DemoService to ...

  8. JavaScirpt(JS)——js介绍及ECMAScript

    一.JavaScript历史发展 JavaScript语言的历史:http://javascript.ruanyifeng.com/introduction/history.html 1994年12月 ...

  9. 视觉库—OpenCV

    视频会议软件的视频质量除了与外置设备.编码器相关外,还与视频的后处理技术相关,视频图像通过后处理技术,如图像增强.图像去噪等,图像质量会得到主观上较大的提高.而我们通常的视频后处理技术会采用开源的项目 ...

  10. Linux中怎么从root用户切换到普通用户

    su是在用户间切换,可以是从普通用户切换到root用户, test@ubuntu:~$ su Password:  root@ubuntu:/home/test# 也可以是从root用户切换到普通用户 ...