#include "jni.h" #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <android/log.h> #include <pthread.h> #define TAG "Test_JNI" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) /** * 获取文件大小 * @param path 文件路径 * @return */ long get_file_size(char* path){ FILE *fp = fopen(path,"rb"); fseek(fp,0,SEEK_END); long ret = ftell(fp); fclose(fp); return ret; } /** * 文件拆分 */ JNIEXPORT void JNICALL nativeDiff( JNIEnv * env, jclass clazz,jstring path,jstring pattern_path,jint file_num){ LOGI("开始分割"); const char *path_str = (*env)->GetStringUTFChars(env,path,NULL); const char *path_pattern_str = (*env)->GetStringUTFChars(env,pattern_path,NULL); //申请字符串数组 char **patches = (char **)malloc(sizeof(char*) * file_num); if(patches == NULL){ return; } //给没一个文件命名 int i = 0; long j = 0; for(i = 0;i<file_num;i++){ patches[i] = (char*)malloc(sizeof(char)*100); if(patches[i] == NULL){ return; } sprintf(patches[i],path_pattern_str,i); } int file_size = get_file_size(path_str); FILE *fpr = fopen(path_str,"rb"); /* * 1.判断文件大小能够被 file_num整除 * 2.能整除就平分 * 3.不能整除就先分 file_num -1 * */ if(file_size%file_num == 0){ long part = file_size/file_num; for(i = 0;i<file_num;i++){ FILE *fpw = fopen(patches[i],"wb"); for(j = 0;j<part;j++){ fputc(fgetc(fpr),fpw); } fclose(fpw); } } else{ long part = file_size/(file_num-1); for(i = 0;i<file_num-1;i++){ FILE *fpw = fopen(patches[i],"wb"); for(j = 0;j<part;j++){ fputc(fgetc(fpr),fpw); } fclose(fpw); } FILE *fpw = fopen(patches[file_num-1],"wb"); for(j = 0;j<file_size%(file_num-1);j++){ fputc(fgetc(fpr),fpw); } fclose(fpw); } fclose(fpr); //释放文件 for(int i=0;i<file_num;i++){ free(patches[i]); patches[i] = NULL; } //释放字符串数组 free(patches); (*env)->ReleaseStringUTFChars(env,path,path_str); (*env)->ReleaseStringUTFChars(env,pattern_path,path_pattern_str); LOGI("拆分结束"); } /** * 文件合并 */ JNIEXPORT void JNICALL nativePatch( JNIEnv * env, jclass clazz,jstring merge_path,jstring pattern_path,jint file_num){ const char *path_merge = (*env)->GetStringUTFChars(env,merge_path,NULL); const char *path_pattern = (*env)->GetStringUTFChars(env,pattern_path,NULL); char **patchs = malloc(sizeof(char*) * file_num); int i; long j; long part_size; for(i = 0;i<file_num;i++){ patchs[i] = malloc(sizeof(char)*100); sprintf(patchs[i],path_pattern,i); } FILE *fpw = fopen(path_merge,"wb"); for(i = 0;i<file_num;i++){ part_size = get_file_size(patchs[i]); FILE *fpr = fopen(patchs[i],"rb"); for(j = 0;j<part_size;j++){ fputc(fgetc(fpr),fpw); } fclose(fpr); } fclose(fpw); for(i = 0;i<file_num;i++){ free(patchs[i]); patchs[i] = NULL; } free(patchs); patchs = NULL; (*env)->ReleaseStringUTFChars(env,merge_path,path_merge); (*env)->ReleaseStringUTFChars(env,pattern_path,path_pattern); } //开启新线程 JavaVM* g_jvm = NULL; jobject g_obj = NULL; /** * 开启新线程后调用的方法 * @param arg * @return */ void *thread_fun(void *arg){ JNIEnv *env; jclass cls; jmethodID md,md1; if((*g_jvm)->AttachCurrentThread(g_jvm,&env,NULL) != JNI_OK){ LOGI("%s AttachCurrentThread error failed ",__FUNCTION__); return NULL; } cls = (*env)->GetObjectClass(env,g_obj); if(cls == NULL){ LOGI("findClass error...."); goto error; } md = (*env)->GetStaticMethodID(env,cls,"formJni","(I)V"); if(md == NULL){ LOGI("GetStaticMethodID error...."); goto error; } (*env)->CallStaticVoidMethod(env,cls,md,(int)arg); error: if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK){ LOGI("%s DetachCurrentThread error failed ",__FUNCTION__); } pthread_exit(0); } //设置jniEnv 在Java的方法中调用 JNIEXPORT void JNICALL setJniEnv( JNIEnv * env, jobject jobj){ (*env)->GetJavaVM(env,&g_jvm); g_obj = (*env)->NewGlobalRef(env,jobj); } //开启新线程 在Java的方法中调用 JNIEXPORT void JNICALL newJniThread( JNIEnv * env, jobject jobj){ LOGI("开始开启线程"); int i; pthread_t pt[5]; for(i=0;i<5;i++){ pthread_create(&pt[i],NULL,&thread_fun,(void*)i); } } //动态注册 static const JNINativeMethod getMethods[] = { {"diff","(Ljava/lang/String;Ljava/lang/String;I)V",(void *)nativeDiff}, {"patch","(Ljava/lang/String;Ljava/lang/String;I)V",(void *)nativePatch} }; static const JNINativeMethod getMainActivityMethods[] = { {"setJniEnv","()V",(void *)setJniEnv}, {"newJniThread","()V",(void *)newJniThread} }; static int registerNatives(JNIEnv *env){ LOGI("注册FileUtils方法调用"); jclass clazz; clazz = (*env)->FindClass(env,"cn/cct/lsn9/FileUtils"); if(clazz == NULL){ LOGI("注册方法调用失败"); return JNI_FALSE; } if((*env)->RegisterNatives(env,clazz,getMethods,NELEM(getMethods)) < 0){ LOGI("注册FileUtils失败"); return JNI_FALSE; } return JNI_TRUE; } static int registerMainActivityNative(JNIEnv *env){ LOGI("注册MainActivity方法调用"); jclass clazz; clazz = (*env)->FindClass(env,"cn/cct/lsn9/MainActivity"); if(clazz == NULL){ LOGI("注册MainActivity失败"); return JNI_FALSE; } if((*env)->RegisterNatives(env,clazz,getMainActivityMethods,NELEM(getMainActivityMethods)) < 0){ LOGI("注册MainActivity失败"); return JNI_FALSE; } return JNI_TRUE; } JNIEXPORT jint JNI_OnLoad(JavaVM * vm,void *reserved){ LOGI("JNI_OnLoad函数开始调用"); JNIEnv *env = NULL; if((*vm)->GetEnv(vm,(void**) &env,JNI_VERSION_1_4) != JNI_OK){ LOGI("获取env失败"); return -1; } assert(env != NULL); registerNatives(env); registerMainActivityNative(env); return JNI_VERSION_1_4; }
C文件拆分和合并 JNI中开启新线程
最新推荐文章于 2022-11-14 18:22:57 发布