Android(Java):jni源代码
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("测试ndk");
btn.setOnClickListener(new
ButtonOnClickListener());
setContentView(btn);
Toast.makeText(getApplicationContext(), PATH,
Toast.LENGTH_LONG).show();
}
public final class
ButtonOnClickListener implements OnClickListener{
@Override
public void onClick(View arg0)
{
// TODO Auto-generated method
stub
byte[] data =
"zhanghongliu".getBytes();
FileInputStream fis =
null;
FileOutputStream fos = null;
int
i = 0;
for(i=1;i<=200000;i++){
try
{
fis = new
FileInputStream(RESOURCEPATH);
int size =
fis.available();
data = new
byte[size];
fis.read(data, 0,
size);
String result =
FileJNILib.videoCrypt(data,ENCRYPTPATH);
Toast.makeText(getApplicationContext(),
result,
Toast.LENGTH_LONG).show();
data =
FileJNILib.videoDerypt(ENCRYPTPATH);
fos = new
FileOutputStream(DECRYPTPATH);
fos.write(data);
} catch (FileNotFoundException
e) {
// TODO Auto-generated catch
block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated
catch
block
e.printStackTrace();
}finally{
try
{
if(null !=
fis){
fis.close();
}
if(null
!=
fos){
fos.close();
}
data
= null;
} catch (IOException e)
{
// TODO Auto-generated catch
block
e.printStackTrace();
}
}
Log.i("count", i+"");
//data = null;
}
//Toast.makeText(getApplicationContext(), new String(data),
Toast.LENGTH_LONG).show();
//show();
}
public
void show(){
File newfile = new
File(PATH);
FileInputStream
inStream = null;
try {
inStream
= new FileInputStream(newfile);
} catch
(FileNotFoundException e) {
// TODO Auto-generated
catch
block
//e.printStackTrace();
}
String content =
FileUtil.readInStream(inStream);
Log.i("FileText", content);
Toast.makeText(getApplicationContext(), content,
Toast.LENGTH_LONG).show();
}
}
public static String readInStream(FileInputStream
inStream){
try {
ByteArrayOutputStream
outStream = new ByteArrayOutputStream();
byte[] buffer =
new byte[1024];
int length =
-1;
while((length = inStream.read(buffer)) != -1
){
outStream.write(buffer, 0,
length);
}
outStream.close();
inStream.close();
return
outStream.toString();
} catch (IOException e)
{
Log.i(TAG,
e.getMessage());
}
return null;
}
public class FileJNILib {
static
{
System.loadLibrary("filejni");
}
public static native String videoCrypt(byte[] content, String
dest_file);
public static native byte[] videoDerypt(String
dest_file);
public static native String videoDerypt(String dest_file,
ByteArrayOutputStream outputstream);
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <jni.h> //jni的主要头文件
#include <android/log.h>
#define LOG_TAG "JNI"
#define LOGI(...)
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
/* Header for
class com_test_jni_FileJNILib */
/*
* Class:
com_test_jni_FileJNILib
* Method:
videoCrypt
* Signature:
([BLjava/lang/String;)V
*/
JNIEXPORT jstring JNICALL
videoCrypt
(JNIEnv * env, jclass thiz, jbyteArray content, jstring
dest_file){
//env->GetStringUTFChars(source,NULL);
const char *path = (*env)->GetStringUTFChars(env, dest_file,
NULL);
LOGI(path);
FILE *fp =
fopen(path,"wb");
if(fp==NULL){
LOGI("fopen
error");
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
return (*env)->NewStringUTF(env, "fopen
error");
}
char *data =
(*env)->GetByteArrayElements(env,content, 0);
int size =
(*env)->GetArrayLength(env,content);
//int iLen =
sizeof(data);//C语言中判断数据类型或者表达式长度符
LOGI("file size is %d",
size);
crypt(data,size);
/******文件写入方法***********/
//fputc(‘c‘,fp);
//fputs(data,fp);
fwrite(data,size,1,fp);
//fprintf(fp,"%s",data);
/*****************/
fclose(fp);
(*env)->ReleaseByteArrayElements(env,content,data,0);
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
LOGI("execute complete");
return
(*env)->NewStringUTF(env, "encrypt successful");
}
/*
* Class:
com_test_jni_FileJNILib
* Method:
videoDerypt
* Signature:
(Ljava/lang/String;)[B
*/
JNIEXPORT jbyteArray JNICALL
videoDerypt
(JNIEnv * env, jclass thiz, jstring
dest_file){
const char *path =
(*env)->GetStringUTFChars(env, dest_file,
NULL);
LOGI(path);
/*****得到文件长度*******/
int
size;
struct stat tFileStat;
if(
stat(path, &tFileStat )
)
{
LOGI("file not found
error");
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
return
NULL;
}
size=tFileStat.st_size;
LOGI("file
size is %d",size);//报错 int
/************/
/*****分配内存*******/
char *temp =
NULL;
temp=(char*)malloc(size);
if(temp
== NULL)
{
LOGI("malloc
error");
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
return
NULL;
}
//
memset(temp,0x00,size*sizeof(char)+1);//初始化内存
/************/
FILE *fp =
fopen(path,"rb");
if(fp==NULL){
LOGI("fopen
error");
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
free(temp);//释放内存
temp=NULL;
return
NULL;
}
/******文件读方法***********/
//fgetc(fp);
//fgets(temp,100,fp);
fread(temp,size,1,fp);
//fscanf(fp,"%s",temp);
/*****************/
fclose(fp);
crypt(temp,size);
jbyteArray jarrRV
=(*env)->NewByteArray(env,size);
jbyte *jby
=(*env)->GetByteArrayElements(env,jarrRV,
0);
memcpy(jby, temp,
size);//复制数据
(*env)->SetByteArrayRegion(env,jarrRV,
0,size, jby);//将Jbyte
转换为jbarray数组
(*env)->ReleaseByteArrayElements(env,jarrRV,jby,0);//释放jby数组*
解决长时间运行退出问题
内部引用超过指定数量
//(*env)->DeleteLocalRef(env,jarrRV);//影响程序
//(*env)->DeleteLocalRef(env,temp);//不对
一般用malloc申请内存,free释放
free(temp);
temp=NULL;
(*env)->ReleaseStringUTFChars(env,dest_file,
path);
LOGI("execute
complete");
return jarrRV;
}
void crypt(char *data, int size){
int i;
char
sPwd[]="************************";
int pwdLen =
sizeof(sPwd);
//LOGI("dongao.com mobile_encrypt
%d",pwdLen);
int count=0;
for(i=0; i<size;
i++)
{
if(count >= pwdLen) count =
0;
data[i]=data[i]^sPwd[count++];
//LOGI("%c",sPwd[count
>= 10 ?count=0:count++]);
}
}
/*
* Class:
com_test_jni_FileJNILib
* Method:
videoDerypt
* Signature:
(Ljava/lang/String;Ljava/io/ByteArrayOutputStream;)V
*/
JNIEXPORT
jstring JNICALL videoDerypt2ByteArray
(JNIEnv * env, jclass thiz,
jstring dest_file, jobject outputstream){
return NULL;
}
static const JNINativeMethod gMethods[] = {
//定义批量注册的数组,是注册的关键部分
{"videoCrypt",
"([BLjava/lang/String;)Ljava/lang/String;", (void*)videoCrypt} ,//
func2是在java中声明的native函数名,"()V"是函数的签名,可以通过javah获取。
{"videoDerypt",
"(Ljava/lang/String;)[B", (void*)videoDerypt},
{"videoDerypt",
"(Ljava/lang/String;Ljava/io/ByteArrayOutputStream;)Ljava/lang/String;",
(void*)videoDerypt2ByteArray}
};
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void *reserved)
//这是JNI_OnLoad的声明,必须按照这样的方式声明
{
JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
jint result = -1;
if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
//从JavaVM获取JNIEnv,一般使用1.4的版本
return -1;
jclass clazz;
static const char* const kClassName="com/test/jni/FileJNILib";
clazz = (*env)->FindClass(env, kClassName); //这里可以找到要注册的类,前提是这个类已经加载到java虚拟机中。 这里说明,动态库和有native方法的类之间,没有任何对应关系。
if(clazz == NULL)
{
LOGI("cannot get class:%s\n", kClassName);
return -1;
}
if((*env)->RegisterNatives(env, clazz,gMethods, sizeof(gMethods)/sizeof(gMethods[0]))!= JNI_OK) //这里就是关键了,把本地函数和一个java类方法关联起来。不管之前是否关联过,一律把之前的替换掉!
{
LOGI("register native method failed!\n");
return -1;
}
return JNI_VERSION_1_4; //这里很重要,必须返回版本,否则加载会失败。
}
原文 http://blog.csdn.net/zhanghongliu1122/article/details/9411921