NDK编程的步骤
(前提:eclipse拥有ndk编程环境. 此工程演示文件拆分、合并的功能)
-
新建Android工程(废话)
创建类编写java层native方法
/**
* 拆分
* @param path 文件原始路径
* @param path_pattern 拆分的路径
* @param count 拆分的个数
*/
public native static void diff(String path,String path_pattern,int count);
/**
* 合并
* @param path_pattern 拆分的文件
* @param count 个数
* @param merge_path 合并后的文件
*/
public native static void patch(String path_pattern,int count,String merge_path);
3.使用javah命令 生成.h头文件(命令行进入src目录后:javah 文件全称)
javah com.ph.ndkfilepatch
4.创建jni目录,将.h头文件放入
5.工作空间引入ndk
6.工程添加本地支持add native support
android tools–>add native support
7.添加路径和符号
工程右键–>Properties
8.实现头文件中定义的函数
//拆分
JNIEXPORT void JNICALL Java_com_dongnaoedu_ndkfilepatch_NDKFileUtils_diff
(JNIEnv *env, jclass jcls, jstring path_jstr,jstring path_pattern_jstr, jint file_num){
//jstring -> char*
//需要分割的文件路径
const char* path = (*env)->GetStringUTFChars(env,path_jstr,NULL);
const char* path_pattern = (*env)->GetStringUTFChars(env,path_pattern_jstr,NULL);
//得到分割之后的子文件的路径列表
char **patches = malloc(sizeof(char*) * file_num);
int i = 0;
for (; i < file_num; i++) {
patches[i] = malloc(sizeof(char) * 100);
//元素赋值
//需要分割的文件:C://jason/liuyan.png
//子文件:C://jason/liuyan_%d.png
sprintf(patches[i], path_pattern, (i+1));
LOGE("patch path:%s",patches[i]);
}
//不断读取path文件,循环写入file_num个文件中
// 整除
// 文件大小:90,分成9个文件,每个文件10
// 不整除
// 文件大小:110,分成9个文件,
// 前(9-1)个文件为(110/(9-1))=13
// 最后一个文件(110%(9-1))=6
int filesize = get_file_size(path);
FILE *fpr = fopen(path,"rb");
//整除
if(filesize % file_num == 0){
//单个文件大小
int part = filesize / file_num;
i = 0;
//逐一写入不同的分割子文件中
for (; i < file_num; i++) {
FILE *fpw = fopen(patches[i], "wb");
int j = 0;
for(; j < part; j++){
//边读边写
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
}
else{
//不整除
int part = filesize / (file_num - 1);
i = 0;
//逐一写入不同的分割子文件中
for (; i < file_num - 1; i++) {
FILE *fpw = fopen(patches[i], "wb");
int j = 0;
for(; j < part; j++){
//边读边写
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
//the last one
FILE *fpw = fopen(patches[file_num - 1], "wb");
i = 0;
for(; i < filesize % (file_num - 1); i++){
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
//关闭被分割的文件
fclose(fpr);
//释放
i = 0;
for(; i < file_num; i++){
free(patches[i]);
}
free(patches);
(*env)->ReleaseStringUTFChars(env,path_jstr,path);
(*env)->ReleaseStringUTFChars(env,path_pattern_jstr,path_pattern);
}
//合并
JNIEXPORT void JNICALL Java_com_dongnaoedu_ndkfilepatch_NDKFileUtils_patch
(JNIEnv *env, jclass jcls,jstring path_pattern_jstr, jint file_num,jstring merge_path_jstr){
//合并之后的文件
const char* merge_path = (*env)->GetStringUTFChars(env,merge_path_jstr,NULL);
//分割子文件的pattern
const char* path_pattern = (*env)->GetStringUTFChars(env,path_pattern_jstr,NULL);
//得到分割之后的子文件的路径列表
char **patches = malloc(sizeof(char*) * file_num);
int i = 0;
for (; i < file_num; i++) {
patches[i] = malloc(sizeof(char) * 100);
//元素赋值
//需要分割的文件:C://jason/liuyan.png
//子文件:C://jason/liuyan_%d.png
sprintf(patches[i], path_pattern, (i+1));
LOGE("patch path:%s",patches[i]);
}
FILE *fpw = fopen(merge_path,"wb");
//把所有的分割文件读取一遍,写入一个总的文件中
i = 0;
for(; i < file_num; i++){
//每个子文件的大小
int filesize = get_file_size(patches[i]);
FILE *fpr = fopen(patches[i], "rb");
int j = 0;
for (; j < filesize; j++) {
fputc(fgetc(fpr),fpw);
}
fclose(fpr);
}
fclose(fpw);
//释放
i = 0;
for(; i < file_num; i++){
free(patches[i]);
}
free(patches);
(*env)->ReleaseStringUTFChars(env,path_pattern_jstr,path_pattern);
(*env)->ReleaseStringUTFChars(env,merge_path_jstr,merge_path);
}
9.编译生成动态库(.so)
Project–>Build Project
10.加载动态库
static{
System.loadLibrary("NDK_patch");
}