03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写
1 案例场景,通过C语言回调Java的代码,案例的最终界面:
2 案例的代码结构如下:
3 编写DataProvider的代码:
|
package com.example.ndkcallback; public class DataProvider { //C调用java空方法 public void helloFromJava(){ System.out.println("哈哈哈 我被调用了"); } //C调用java中的带两个int参数的方法 public int Add(int x,int y){ int result=x+y; System.out.println("result:"+result); return result; } //C调用java中参数为string的方法 public void printString(String s) { System.out.println(s); } public static void demo(){ System.out.println("哈哈哈,我是静态方法"); } public native void callMethod1(); public native void callMethod2(); public native void callMethod3(); public native void callMethod4(); public native void callMethod5(); } |
4 通过DataProvider获得头文件
接着带有header的结构如下:
5 编写MainActivity代码:
|
package com.example.ndkcallback; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; public class MainActivity extends ActionBarActivity { DataProvider dp; static { System.loadLibrary("hello"); } public void helloFromJava() { System.out.print("哈哈哈,我被调用了"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dp = new DataProvider(); } public void click1(View view){ dp.callMethod1(); } public void click2(View view){ dp.callMethod2(); } public void click3(View view){ dp.callMethod3(); } public void click4(View view){ dp.callMethod4(); } public void click5(View view){ dp.callMethod5(); } } |
6 编写布局文件activity_main.xml:
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:onClick="click1" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="回调java中helloFromJava" /> <Button android:onClick="click2" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/button1" android:text="回调java中Add" /> <Button android:onClick="click3" android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/button2" android:text="回调java中PrintString" /> <Button android:onClick="click4" android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/button3" android:text="回调java中其它类的方法" /> <Button android:onClick="click5" android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/button4" android:text="回调java中静态的方法" /> </RelativeLayout> |
7 接下来,通过javap命令获得DataProvider的方法签名,在cygwin上进入/NdkCallBack/bin/classes.
命令如下:
toto@toto-PC /cygdrive/e/workspace/Android/NdkCallBack/bin/classes
$ javap -scom.example.ndkcallback.DataProvider
上面红框圈的分别是执行命令和方法签名。这个签名在hello.c中会用到。
7 接下来编写hello.c
|
#include "com_example_ndkcallback_DataProvider.h" /** * 调用:DataProvider中的 public void helloFromJava(); */ JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod1 (JNIEnv *env, jobject jobject) { /** * Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider"); * Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{}); * declaredMethod.invoke(forName.newInstance(), new Object[]{}); */ //jclass (*FindClass)(JNIEnv*, const char*); jclass clazz = (*env)->FindClass(env,"com/example/ndkcallback/DataProvider"); //jmethodID (*GetMethodID)(JNIEnv*,jclass,const char*,const char*) //方法签名 参数和返回值 //GetMethodID中参数分别是env指针,class,方法名,方法签名 jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V"); //通过 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);来调用Java的代码 (*env)->CallVoidMethod(env,jobject,methodId); } /** * 调用:DataProvider中的 public int Add(int, int); */ JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod2 (JNIEnv *env, jobject jobject) { jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider"); //这里的方法签名中有几个I表示有几个参数 jmethodID methodId=(*env)->GetMethodID(env,clazz,"Add","(II)I"); // jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)->CallIntMethod(env,jobject,methodId,3,5); } /** * 调用:DataProvider中的 public void printString(java.lang.String); */ JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod3 (JNIEnv *env, jobject jobject) { // 参数 object 就是native方法所在的类 jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider"); jmethodID methodId=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V"); // jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); jstring str=(*env)->NewStringUTF(env,"hello"); (*env)->CallVoidMethod(env,jobject,methodId,str); } JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod4 (JNIEnv * env, jobject j){ jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/MainActivity"); // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); // 方法签名 参数和返回值 jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V"); // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); // 需要创建DataProvider的 对象 // jobject (*AllocObject)(JNIEnv*, jclass); jobject obj=(*env)->AllocObject(env,clazz); // new MainActivity(); (*env)->CallVoidMethod(env,obj,methodId); } JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod5 (JNIEnv * env, jobject j){ jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider"); // jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); jmethodID methodid=(*env)->GetStaticMethodID(env,clazz,"demo","()V"); //void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); (*env)->CallStaticVoidMethod(env,clazz,methodid); } |
8 编写Android.mk文件,内容如下:
|
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libhello LOCAL_SRC_FILES := Hello.c include $(BUILD_SHARED_LIBRARY) |
9 编写Android的清单文件,内容如下:
|
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.ndkcallback" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.ndkcallback.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
10 交叉编译,生成.so文件
成功之后,查看Android控制台打印的结果
03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写的更多相关文章
- Android NDK开发之C调用Java及原生代码断点调试(二)
上一篇中,我们主要学习了Java调用本地方法,并列举了两大特殊实例来例证我们的论据,还没学习的伙伴必须先去阅读下,本次的学习是直接在上一篇的基础上进行了.点击:Android NDK开发之从Java与 ...
- C++ 跨语言调用 Java
C++ 跨语言调用 Java Java JDK 提供了 JNI 接口供 C/C++ 程序调用 Java 编译后的类与方法,主要依赖于头文件(jni.h) 和 动态库(jvm.so/jvm.dll),由 ...
- HAL中通过JNI调用java方法【转】
转载请注明本文出处:http://www.cnblogs.com/xl19862005 作者:Xandy 由于工作的需要,最近一直在研究HAL.JNI.Java方法之间互调的问题,并做了如下一些记录和 ...
- JNI系列——C文件中的方法调用Java中方法
1.创建xxx.jni包并在该包下实现一些Java的方法,和要调用的本地方法 2.实现MainActivity中的按钮点击事件-即点击按钮调用本地的方法 3.在C文件中的方法中回调Java的方法 3. ...
- Android NDK开发之Jni调用Java对象
https://my.oschina.net/zhiweiofli/blog/114064 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instan ...
- Webview 中 Javascript 无法调用 Java 对象
[问题产生] Webview 通过 addjavascriptInterface 传递对象给前端,一切正常.但是 Android官方已提醒此功能是有安全风险,改用 safe-java-js-webvi ...
- JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程
JNI/NDK Java调用C/C++前言 通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...
- NDK(19)简单示例:ndk调用java基本方法、数组;使用stl、访问设备
一.ndk调用java类示例 1,调用基本方法 /* * Class: com_example_ndksample_MainActivity * Method: ndkFindJavaClass * ...
- Android NDK开发(1)----- Java与C互相调用实例详解
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/13/2394153.html 一.概述 对于大部分应用开发者来说可能都不怎么接触到NDK,但如果 ...
随机推荐
- CSAPP缓冲区溢出攻击实验(下)
CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...
- Spark编译及spark开发环境搭建
最近需要将生产环境的spark1.3版本升级到spark1.6(尽管spark2.0已经发布一段时间了,稳定可靠起见,还是选择了spark1.6),同时需要基于spark开发一些中间件,因此需要搭建一 ...
- rbac数据库设计
1 rbac数据库设计 RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制分享牛原创,分享牛系列,分享牛.rbac 用户角色权限资源表如 ...
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 安卓Button-TextView-EditText综合运用
1.如何使用安卓中的按键Button? 1.先从控件库拖一个按钮button的控件,在XML设置好宽高等参数 对应的就是Button这个图标,直接拖出来即可; 以下是设置这个按钮对应的XML代码: & ...
- Android判断当前系统语言
Android获取当前系统语言 getResources().getConfiguration().locale.getCountry() 国际化常用语言 中文: getResources().get ...
- 3.QT数据库综合案例,模糊查询等操作
1 新建一个项目: Database01.pro SOURCES += \ main.cpp \ Contact.cpp QT += gui widgets sql CONFIG += C++1 ...
- SpringMVC实现用户登录实例
今天分享一下SpringMVC的一个登陆小案例 准备工作 创建一个Dynamic Web Project(本人是Eclipse) 添加相关的jar包,构建路径 创建springMVC-servlet. ...
- (NO.00005)iOS实现炸弹人游戏(十):游戏主角(三)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面我们来看游戏主角类里面几个播放特殊动画的方法,首先从run ...
- Cocos2D游戏项目CCTableView在Xcode7.2下的无法滚动问题
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个RPG游戏转换到Xcode7.2下发现一个问题,原来可以上 ...