ToB企服应用市场:ToB评测及商务社交产业平台

标题: Android之JNI开发入门 [打印本页]

作者: 王國慶    时间: 2024-12-1 16:00
标题: Android之JNI开发入门
   what 什么是JNI
     
   
   
     why 为什么要用JNI
     
   
  1. *   ①java运行在虚拟机上 JNI可以扩展java虚拟机的能力 让java代码可以调用驱动
复制代码
  
  1. *   ②java是解释型语言 运行效率相对较低 C/C++的效率要高很多 通过jni把耗时操作方法C/C++可以提高java运行效率
复制代码
  
  1. *   ③ java代码编译成的.class 文件安全性较差, 可以通过jni 把重要的业务逻辑放到c/c++去实现,c/c++反编译比较困难 安全性较高
复制代码
   
     怎么用JNI
     
   
   
  警告!!!
=====
写完之后一定要记得加载动态链接库
static {
System.loadLibrary(“hello”);
}
1.交叉编译
======

2. jni开发工具
===========

3. jni helloworld
==================
- jni开发的步骤

1.写Java代码 声明本地方法,用到native关键字,本地方法不消去实现
2.项目根目录下创建jni文件夹
3.在jni文件夹下创建.c文件

jstring Java_com_xfhy_jnihelloworld_MainActivity_helloFromC(JNIEnv* env,jobject thiz){
char* str = “hello from c!”;
//到jni.h中找到如下方法 jstring (NewStringUTF)(JNIEnv, const char*);
return (*env)->NewStringUTF(env,str);
}
函数中必须有2个形参:JNIEnv* env,jobject thiz;如果java中的native函数有形参的话,则必要把这些形到场在JNIEnv* env,jobject thiz这个2个形参之后.
4.导入
4. jni开发中的常见错误
===============

在jni目录下创建 Application.mk 在里面指定
APP_ABI := armeabi x86
APP_PLATFORM := android-14

使用方法:javah com.xfhy.jnihelloworld.MainActivity

5.jni简便开发流程
===========

usr 目录下 arch-arm -> include 确定后 会解决代码提示和报错的题目

static {
System.loadLibrary(“hello”); //加载动态链接库
}
6. Java向C通报一些基本的范例,处置处罚
======================
将一个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;
}
int范例
JNIEXPORT jint JNICALL Java_com_xfhy_javapassdata_JNI_add
(JNIEnv * env, jobject clazz, jint x, jint y){
return x+y; //直接返回x+y
}
String范例
JNIEXPORT jstring JNICALL Java_com_xfhy_javapassdata_JNI_sayHelloInC
(JNIEnv *env, jobject clazz, jstring str){
//将jstring转换成char* 范例
char* cstr = _JString2CStr(env,str);
//调用C语言的strlen丈量cstr字符串的长度
int length = strlen(cstr);
int i=0;
for(i=0; i<length; i++){
*(cstr+i) += 1; //将字符串+1
}
return (env)->NewStringUTF(env,cstr); //将char 范例转换成String范例返回
}
int[]范例
JNIEXPORT jintArray JNICALL Java_com_xfhy_javapassdata_JNI_arrElementsIncrease
(JNIEnv *env, jobject clazz, jintArray jArray) {
//jsize (GetArrayLength)(JNIEnv, jarray); 返回数组长度
int length = (*env)->GetArrayLength(env,jArray);
//jint* (GetIntArrayElements)(JNIEnv, jintArray, jboolean*); 末了一个参数表示是否拷贝,可以不消传值
//返回int* 返回该数组的首所在 如许就可以直接通过该指针直接操作该数组了
int* cArray = (*env)->GetIntArrayElements(env,jArray,NULL);
int i;
for(i=0; i<length; i++) {
*(cArray+i) += 10;
}
return jArray; //直接将原数组返回(这时已经是修改过了的)
}
7.C代码中向logcat输出内容
=================
1.Android.mk文件增加以下内容
LOCAL_LDLIBS += -llog
2.C代码中增加以下内容
#include <android/log.h>
#define LOG_TAG “xfhy”
#define LOGD(…) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, VA_ARGS)
#define LOGI(…) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, VA_ARGS)

8. C代码回调java方法
===============
起首必要相识:
Java反射
public class Demo {

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4