JNI开发第二篇通过反射实现C中调用java代码,并实现Log打印日志
来源:互联网 发布:复杂网络的实际应用 编辑:程序博客网 时间:2024/05/21 14:43
C中调用java代码,主要运用在C代码执行耗时操作时候来进行对UI的实时性的改变,比如做图像处理的时候,可能图像较大,处理时间较长,那么就可以通过这个技术来实时更新处理的进度,下面我们通过代码来看具体的实现。
1.MainActivity
public class MainActivity extends Activity { JNI jni; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); jni = new JNI(this); } public void callbackvoid(View v){ jni.callbackvoidmethod(); } public void callbackint(View v){ jni.callbackintmethod(); } public void callbackString(View v){ jni.callbackStringmethod(); } public void callbackshowtoast(View v){ jni.callbackShowToast(); }}
2.JNI.java
public class JNI { static{ System.loadLibrary("callback"); } private Context mContext; public JNI(Context context){ mContext = context; } public native void callbackvoidmethod(); public native void callbackintmethod(); public native void callbackStringmethod(); public native void callbackShowToast(); //C调用java空方法 public void helloFromJava(){ System.out.println("hello from java"); } //C调用java中的带两个int参数的方法 public int add(int x,int y) { return x+y; } //C调用java中参数为string的方法 public void printString(String s){ System.out.println(s); } public void showToast(String s){ Toast.makeText(mContext, s, Toast.LENGTH_LONG).show(); }}
3.activity_main.xml
<LinearLayout 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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.mengxin.callbackjava.MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="callbackvoid" android:text="回调空方法" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="callbackint" android:text="回调int参数方法" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="callbackString" android:text="回调String参数方法" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="callbackshowtoast" android:text="回调弹吐司" /></LinearLayout>
4.接下来是JNI的类文件命名为callback.c
#include <jni.h>#include <stdlib.h>#include "eben_hpc_log.h"/** * 把一个jstring转换成一个c语言的char* 类型. */char* _JString2CStr(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = (*env)->FindClass(env, "java/lang/String"); jstring strencode = (*env)->NewStringUTF(env,"GB2312"); jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312"); jsize alen = (*env)->GetArrayLength(env, barr); jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE); if(alen > 0) { rtn = (char*)malloc(alen+1); //"\0" memcpy(rtn, ba, alen); rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env, barr, ba,0); return rtn;}JNIEXPORT void JNICALL Java_com_mengxin_callbackjava_JNI_callbackvoidmethod (JNIEnv * env, jobject clazz){ //jclass (*FindClass)(JNIEnv*, const char*); //① 获取字节码对象 jclass claz = (*env)->FindClass(env,"com/mengxin/callbackjava/JNI"); //②获取Method对象 //jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); jmethodID methodID =(*env)->GetMethodID(env,claz,"helloFromJava","()V"); //③通过字节码对象创建一个Object //④通过对象调用方法 //void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)->CallVoidMethod(env,clazz,methodID);}JNIEXPORT void JNICALL Java_com_mengxin_callbackjava_JNI_callbackintmethod (JNIEnv * env, jobject clazz){ //① 获取字节码对象 jclass claz =(*env)->FindClass(env,"com/mengxin/callbackjava/JNI"); //②获取Method对象 jmethodID methodID = (*env)->GetMethodID(env,claz,"add","(II)I"); //jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); int result =(*env)->CallIntMethod(env,clazz,methodID,3,4); LOGD("result = %d",result);}JNIEXPORT void JNICALL Java_com_mengxin_callbackjava_JNI_callbackStringmethod (JNIEnv * env, jobject clazz){ //① 获取字节码对象 jclass claz =(*env)->FindClass(env,"com/mengxin/callbackjava/JNI"); //② 获取Method对象 jmethodID methodid =(*env)->GetMethodID(env,claz,"printString","(Ljava/lang/String;)V"); // jstring result =(*env)->NewStringUTF(env,"hello from c"); (*env)->CallVoidMethod(env,clazz,methodid,result);}JNIEXPORT void JNICALL Java_com_mengxin_callbackjava_JNI_callbackShowToast (JNIEnv * env, jobject clazz){ jclass claz =(*env)->FindClass(env,"com/mengxin/callbackjava/JNI"); jmethodID methodid =(*env)->GetMethodID(env,claz,"showToast","(Ljava/lang/String;)V"); //jobject (*AllocObject)(JNIEnv*, jclass); //通过字节码对象创建 java对象 在这儿就是创建了mainactivity的对象 //jobject obj =(*env)->AllocObject(env,claz); jstring result =(*env)->NewStringUTF(env,"hello from c"); //void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)->CallVoidMethod(env,clazz,methodid,result);}
5.如果是要打Log,还需要一个文件eben_hpc_log.h
#ifndef _Included_hpc_Log#define _Included_hpc_Log#ifdef __cplusplusextern "C" {#endif#include <android/log.h>// 宏定义类似java 层的定义,不同级别的Log LOGI, LOGD, LOGW, LOGE, LOGF。 对就Java中的 Log.i log.d#define LOG_TAG "hpc -- JNILOG" // 这个是自定义的LOG的标识//#undef LOG // 取消默认的LOG#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__)#ifdef __cplusplus}#endif#endif
6.最后修改的是build.gradle
apply plugin: 'com.android.application'android { compileSdkVersion 24 buildToolsVersion "24.0.1" defaultConfig { applicationId "com.mengxin.callbackjava" minSdkVersion 15 targetSdkVersion 24 versionCode 1 versionName "1.0" ndk { ldLibs "log" moduleName "callback" //生成的so名字 //abiFilters "armeabi" //输出指定三种abi体系结构下的so库。目前可有可无。 abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。目前可有可无。 } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.2.0'}
源码链接
参考文献
http://www.cnblogs.com/0616–ataozhijia/p/5628291.html
0 0
- JNI开发第二篇通过反射实现C中调用java代码,并实现Log打印日志
- jni开发中在c文件中打印log日志
- NDK 开发C中通过反射调用Java代码
- JNI开发之c代码中LOG打印调试信息
- 使用jni实现在C语言中打印log信息
- androidstudio调用jni实现日志打印
- androidstudio调用jni实现日志打印
- JNI编程中C调用Java实现。
- Android Studio中通过jni实现对C/C++代码的调用,HelloJni,Ubuntu
- JNI实现java调用C语言实现底层代码
- Android开发 通过JNI实现JAVA与C/C++程序间的调用和回调
- JNI 实现LOG打印功能
- Android中调用c函数来打印log---(JNI)
- android 调用jni 并打印log
- Android jni 开发中C/C++层打印Log信息
- 02_JNI中Java代码调用C代码,Android中使用log库打印日志,javah命令的使用,Android.mk文件的编写,交叉编译
- 11.Android之JNI实现函数中LOG打印
- Java通过反射实现方法调用
- 专业测评:iphone7致命缺陷曝光
- hdoj3664【DP】
- 友盟分享bug整理
- 【给将来学神的算法详解--高精】(4)对消与还原
- ROS Learning-022 learning_tf-06(编程) 现在与过去中穿梭 (Python版) --- waitForTransformFull() 函数
- JNI开发第二篇通过反射实现C中调用java代码,并实现Log打印日志
- Struts2中的拦截器
- 51单片机定时控制灯
- 记录一个网站
- JAVA基础6.44——单例设计模式
- 【源码剖析】threadpool —— 基于 pthread 实现的简单线程池
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 9.8
- 第03章:java数据类型