1、定义调用的方法,含完整包名的类:
2、编译这个类,前提是JDK的环境变量配置正确。
3、生成.h头文件
4、生成的头文件内容:
5、实现jni的方法,C语言
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//将java字符串转换为c语言字符串(工具方法)
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 jstring JNICALL Java_com_example_tangyd_1jni_NativeJNI_testJni
(JNIEnv * env, jclass jobject, jstring text){
//定义一个C语言字符串
char* cstr = text;
//返回值是java字符串,所以要将C语言的字符串转换成java的字符串
//在jni.h 中定义了字符串转换函数的函数指针
//jstring (*NewStringUTF)(JNIEnv*, const char*);
//第一种方法:很少用
jstring jstr1 = (*(*env)).NewStringUTF(env, cstr);
//第二种方法,推荐
jstring jstr2 = (*env) -> NewStringUTF(env, cstr);
//return jstr2;
char* c_char = Jstring2CStr(env, text);
int i;
for(i = 0;i<length;i++){
*(cstr+i) += 1; //加密算法,将字符串每个字符加1
}
jstring backstring = (*env)->NewStringUTF(env,c_char);
return backstring;
}
JNIEXPORT jstring JNICALL Java_com_mwp_encodeanddecode_MainActivity_encode
(JNIEnv * env, jobject obj, jstring text, jint length){
char* cstr = Jstring2CStr(env, text);
int i;
for(i = 0;i<length;i++){
*(cstr+i) += 1; //加密算法,将字符串每个字符加1
}
return (*env)->NewStringUTF(env,cstr);
}
JNIEXPORT jstring JNICALL Java_com_mwp_encodeanddecode_MainActivity_decode
(JNIEnv * env, jobject obj, jstring text, jint length){
char* cstr = Jstring2CStr(env, text);
int i;
for(i = 0;i<length;i++){
*(cstr+i) -= 1;
}
return (*env)->NewStringUTF(env, cstr);
}
6、项目根目录下建jni文件夹,把头文件和.c文件放进去(需要回到项目目录下面,不能用eclipse)
7、编写Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testJNI
LOCAL_SRC_FILES := native_jni.c
include $(BUILD_SHARED_LIBRARY)
8、进到项目根目录下打开cmd,生成共享库
发现error,C语言的错误,检查代码吧。
length出错,修改如下:
重新进行共享库生成:
截图1
截图,添加处理器文件夹:
运行提示错误:
10-11 15:19:03.584: D/dalvikvm(21170): No JNI_OnLoad found in /data/app-lib/com.example.tangyd_jni-1/libtestJNI.so 0x4202e968, skipping init
这个错误是没有JNI_OnLoad方法。
再重新生成链接库后报错:
10-11 15:29:39.177: A/libc(23153): Fatal signal 11 (SIGSEGV) at 0x0380001d (code=1), thread 23153 (mple.tangyd_jni)
这个是C语言中的实现问题,数据类型在做转换时,发生的内存问题。
原因是不能直接将jstring赋值给C的char,即
修改:
正确打印的结果:
Window10环境变量截图:
Android的adb
JDK:
NDK: