NDK开发汇总
一 动态注册native方法
#include <android/log.h>
#define TAG "Tim_JNI"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
long get_file_size(const char* path) {
FILE *fp = fopen(path, "rb");
fseek(fp, 0, SEEK_END);
long ret = ftell(fp);
fclose(fp);
return ret;
}
static const JNINativeMethod gMethods[] = {
{
"diff","(Ljava/lang/String;Ljava/lang/String;I)V",(void*)native_diff
},
{
"patch","(Ljava/lang/String;Ljava/lang/String;I)V",(void*)native_patch
}
};
static int registerNatives(JNIEnv* engv)
{
LOGI("registerNatives begin");
jclass clazz;
clazz = (*engv) -> FindClass(engv, "com/dn/tim/dn_lsn_9/FileUtils");
if (clazz == NULL) {
LOGI("clazz is null");
return JNI_FALSE;
}
if ((*engv) ->RegisterNatives(engv, clazz, gMethods, NELEM(gMethods)) < 0) {
LOGI("RegisterNatives error");
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
LOGI("jni_OnLoad begin");
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm,(void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGI("ERROR: GetEnv failed\n");
return -1;
}
assert(env != NULL);
registerNatives(env);
return JNI_VERSION_1_4;
}
二 文件拆分
JNIEXPORT void JNICALL native_diff
(JNIEnv *env, jclass clazz, jstring path, jstring pattern_Path, jint file_num)
{
LOGI("JNI native diff begin");
const char *path_Str = (*env) -> GetStringUTFChars(env, path, NULL);
const char *pattern_Path_str = (*env) ->GetStringUTFChars(env, pattern_Path, NULL);
char **patches = (char **)malloc(sizeof(char *) * file_num);
int i =0;
for (; i < file_num; i++) {
LOGI("char = %d char * = %d", sizeof(char), sizeof(char *));
patches[i] = (char*) malloc(sizeof(char) * 100);
sprintf(patches[i], pattern_Path_str, i);
LOGI("patch path : %s",patches[i]);
}
int fileSize = get_file_size(path_Str);
FILE *fpr = fopen(path_Str, "rb");
if (fileSize % file_num == 0) {
int part = fileSize / file_num;
for (int i =0; i< file_num; i++) {
FILE *fpw = fopen(patches[i], "wb");
for (int j =0; j < part; j++) {
fputc(fgetc(fpr), fpw);
}
fclose(fpw);
}
} else {
int part = fileSize / (file_num - 1);
for (int i =0 ; i< file_num - 1; i++) {
FILE *fpw = fopen(patches[i], "wb");
for (int j =0; j < part; j++) {
fputc(fgetc(fpr), fpw);
}
fclose(fpw);
}
FILE *fpw = fopen(patches[file_num - 1], "wb");
for (int i = 0; i < fileSize % (file_num - 1); i++) {
fputc(fgetc(fpr),fpw);
}
fclose(fpw);
}
fclose(fpr);
for (int i =0; i< file_num; i++) {
free(patches[i]);
}
free(patches);
(*env)->ReleaseStringUTFChars(env, path, path_Str);
(*env)->ReleaseStringUTFChars(env, pattern_Path, pattern_Path_str);
}
三 文件合并
JNIEXPORT void JNICALL native_patch
(JNIEnv *env, jclass clazz, jstring merge_path, jstring pattern_Path, jint file_num)
{
LOGI("JNI native patch begin");
const char *path_Str = (*env) -> GetStringUTFChars(env, merge_path, NULL);
const char *pattern_Path_str = (*env) ->GetStringUTFChars(env, pattern_Path, NULL);
char **patches = (char **)malloc(sizeof(char *) * file_num);
int i =0;
for (; i < file_num; i++) {
patches[i] = (char*) malloc(sizeof(char) * 100);
sprintf(patches[i], pattern_Path_str, i);
LOGI("patch path : %s",patches[i]);
}
FILE *fpw = fopen(path_Str, "wb");
for (int i =0; i < file_num; i++) {
int filesize = get_file_size(patches[i]);
FILE *fpr = fopen(patches[i], "rb");
for (int j =0; j < filesize; j++) {
fputc(fgetc(fpr), fpw);
}
fclose(fpr);
}
fclose(fpw);
for (int i =0; i< file_num; i++) {
free(patches[i]);
}
free(patches);
(*env)->ReleaseStringUTFChars(env, merge_path, path_Str);
(*env)->ReleaseStringUTFChars(env, pattern_Path, pattern_Path_str);
}