您的位置:首页 >聚焦 >

环球观热点:【NDK】封装日志库

2022-12-02 18:39:48    来源:程序员客栈


(资料图片仅供参考)

点击关注,与你共同成长!


【NDK】封装日志库0x1需求 供C++、Java调用控制台输出文件输出(文件大小)设置日志等级0x2 C++ 0x21 LogUtils.h

////Createdby后端码匠on2022/11/30.//#ifndefNDKPRACTICE_LOGUTILS_H#defineNDKPRACTICE_LOGUTILS_H#include#include#include#defineLOG_TAG"km_media_log"#defineLOGD(...)__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)#defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#defineLOGW(...)__android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)#defineLOGE(...)__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)#defineLOG_TEXT_MAX_LENGTH(1024)//单条日志大小#defineLOG_FILE_MAX_SIZE(1024*1024*3)//文件最大为3MBenum{LOG_LEVEL_NONE=0,LOG_LEVEL_ERR=1,LOG_LEVEL_WARNING=2,LOG_LEVEL_INFO=3,LOG_LEVEL_DEBUG=4};#ifdef__cplusplusextern"C"{#endif/***初始化日志选项*@parampFile*@paramfilename*@paramlogLevel*@paramprintScreen*@return*/intLogInit(constchar*pFile,constchar*filename,intlogLevel,intprintScreen);/***日志处理*@paramlevel*@paramstrFormat*@param...*/voidWriteTextLog(intlevel,constchar*strFormat,...);/***向文件中写入日志*@paramlevel*@paramlog*/voidWriteTextLogBottom(intlevel,constchar*log);/***关闭日志库*/voidLogClose();#ifdef__cplusplus}#endif#endif//NDKPRACTICE_LOGUTILS_H

0x22 LogUtils.cpp

////Createdby后端码匠on2022/11/30.//#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include"LogUtils.h"charLOG_FILE_NAME[100]="km_media_log.txt";//日志默认名称//日志级别intg_log_file_level=LOG_LEVEL_NONE;intg_log_screen_level=LOG_LEVEL_NONE;longg_RollingPtr=0;//文件路径staticstd::stringg_logFilePath;intLogInit(constchar*pFile,constchar*filename,intlogLevel,intprintScreen){g_RollingPtr=0;g_log_file_level=logLevel;g_log_screen_level=printScreen;if(filename!=nullptr){strcpy(LOG_FILE_NAME,filename);}if(pFile!=nullptr){g_logFilePath=std::string(pFile)+"/"+LOG_FILE_NAME;}else{g_logFilePath=LOG_FILE_NAME;}return0;}charg_log_info[LOG_TEXT_MAX_LENGTH+100];voidWriteTextLog(intlevel,constchar*strFormat,...){if(level>g_log_file_level&&level>g_log_screen_level){return;}time_tnow;chartimeStr[20];chartemBuf[LOG_TEXT_MAX_LENGTH];time(&now);strftime(timeStr,sizeof(timeStr),"%Y-%m-%d%H:%M:%S",localtime(&now));va_listargs;va_start(args,strFormat);vsnprintf(temBuf,sizeof(temBuf)-1,strFormat,args);va_end(args);switch(level){caseLOG_LEVEL_DEBUG:LOGD("%s",g_log_info);sprintf(g_log_info,"%s[DEBUG]%s\n",timeStr,temBuf);break;caseLOG_LEVEL_INFO:LOGI("%s",g_log_info);sprintf(g_log_info,"%s[INFO]%s\n",timeStr,temBuf);break;caseLOG_LEVEL_WARNING:LOGW("%s",g_log_info);sprintf(g_log_info,"%s[WARN]%s\n",timeStr,temBuf);break;caseLOG_LEVEL_ERR:LOGE("%s",g_log_info);sprintf(g_log_info,"%s[ERROR]%s\n",timeStr,temBuf);break;default:LOGI("%s",g_log_info);sprintf(g_log_info,"%s[NONE]%s\n",timeStr,temBuf);break;}if(level<=g_log_file_level&&!g_logFilePath.empty()){WriteTextLogBottom(level,g_log_info);}}voidWriteTextLogBottom(intlevel,constchar*log){if(level<=g_log_file_level){FILE*fp;structstatinfo{};if(stat(g_logFilePath.c_str(),&info)!=0){g_RollingPtr=0;fp=fopen(g_logFilePath.c_str(),"we");//createfileif(fp==nullptr){LOGE("%s,fopen(w)%sfail,err:%d",__func__,g_logFilePath.c_str(),errno);return;}fprintf(fp,"%s,statfailcreatelogfile,errno:%d\n",__func__,errno);fprintf(fp,"%s",log);fclose(fp);return;}if(info.st_size>=LOG_FILE_MAX_SIZE)//loopwrite{//这里使用复写的方式,保证日志文件不会超过LOG_FILE_MAX_SIZEfp=fopen(g_logFilePath.c_str(),"r+");if(nullptr==fp){LOGE("%s,fopen(r+)%sfail,size:%ld,err:%d",__func__,g_logFilePath.c_str(),info.st_size,errno);return;}if(fseek(fp,g_RollingPtr,SEEK_SET)<0){fclose(fp);return;}g_RollingPtr+=strlen(log);if(g_RollingPtr>info.st_size){g_RollingPtr=0;}}else{fp=fopen(g_logFilePath.c_str(),"a");if(fp==nullptr){LOGE("%s,fopen(a)%sfail,size:%ld,err:%d",__func__,g_logFilePath.c_str(),info.st_size,errno);return;}}fprintf(fp,"%s",log);fclose(fp);}}voidLogClose(){g_log_file_level=LOG_LEVEL_NONE;g_log_screen_level=LOG_LEVEL_NONE;}

0x3 Java 0x31 LogUtils

////Createdby后端码匠on2022/11/30.//packagecn.com.codingce.ndkpractice.utils;importandroid.content.Context;importandroid.os.Environment;importandroid.util.Log;importjava.io.File;publicclassLogUtils{privatestaticContextglobalAplicationContext=null;privatestaticStringPATH_LOGCAT=null;publicenumLogLevel{LOG_LEVEL_NONE,LOG_LEVEL_ERR,LOG_LEVEL_WARNING,LOG_LEVEL_INFO,LOG_LEVEL_DEBUG}publicstaticvoidinit(){if(globalAplicationContext==null)return;booleanobtainSDcardAccess=false;try{obtainSDcardAccess=Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);}catch(Exceptione){Log.e("LogUtils","Exception:"+e.getMessage());}if(obtainSDcardAccess){//优先保存到SD卡中finalFileexternalFilesDir=globalAplicationContext.getExternalFilesDir(null);if(externalFilesDir!=null){PATH_LOGCAT=externalFilesDir.getAbsolutePath()+File.separator+"kmsdk";}else{//如果SD卡不存在,就保存到本应用的目录下PATH_LOGCAT=globalAplicationContext.getFilesDir().getAbsolutePath()+File.separator+"kmsdk";}}else{//如果SD卡不存在,就保存到本应用的目录下PATH_LOGCAT=globalAplicationContext.getFilesDir().getAbsolutePath()+File.separator+"kmsdk";}Filefile=newFile(PATH_LOGCAT);if(!file.exists()){file.mkdirs();}LogInit(PATH_LOGCAT,"km_media_log.txt",4,4);Log.e("LogUtils","curfilediris:"+file.toString());}publicsynchronizedstaticvoidsetApplicationContext(ContextaplicationContext){globalAplicationContext=aplicationContext.getApplicationContext();}//日志类初始化publicstaticnativevoidLogInit(StringlogFilePath,StringlogName,intlogfileLevel,intlogScreenLevel);publicstaticnativevoidlogJni(intlogLevel,Stringcontent);publicstaticnativevoidlogClose();}

0x32 Native

////Createdby后端码匠on2022/11/30.//#include#include#include"LogUtils.h"#definediagnosis_assert(...)assert(__VA_ARGS__)intret=-1;staticvoidnativeLogUtilsRegisterNatives(JNIEnv*jniEnv);JNIEXPORTjintJNICALLJNI_OnLoad(JavaVM*vm,void*reserved){JNIEnv*jniEnv{nullptr};if(vm->GetEnv((void**)&jniEnv,JNI_VERSION_1_6)!=JNI_OK){diagnosis_assert(!"JNIversionerror!");returnJNI_EVERSION;}nativeLogUtilsRegisterNatives(jniEnv);returnJNI_VERSION_1_6;}staticvoidLocalLogInit(JNIEnv*env,jclassclazz,jstringlogFilePath,jstringlogName,jintlogfile_level,jintlog_screen_level){if(ret!=0){constchar*path=env->GetStringUTFChars(logFilePath,JNI_FALSE);constchar*name=env->GetStringUTFChars(logName,JNI_FALSE);intfileLevel=logfile_level;intscreenLevel=log_screen_level;ret=LogInit(path,name,fileLevel,screenLevel);env->ReleaseStringUTFChars(logFilePath,path);env->ReleaseStringUTFChars(logName,name);}}staticvoidlogJni(JNIEnv*env,jclassclazz,jint_level,jstring_str){if(ret!=0){LOGE("logerror!LogInitneed");return;}constchar*str=env->GetStringUTFChars(_str,JNI_FALSE);WriteTextLog(_level,str);env->ReleaseStringUTFChars(_str,str);}staticvoidlogClose(JNIEnv*env,jclassclazz){LogClose();ret=-1;}staticJNINativeMethodnativeUtilsMethods[]={{"LogInit","(Ljava/lang/String;Ljava/lang/String;II)V",(void*)LocalLogInit},{"logJni","(ILjava/lang/String;)V",(void*)logJni},{"logClose","()V",(void*)logClose},};staticvoidnativeLogUtilsRegisterNatives(JNIEnv*jniEnv){if(jniEnv==nullptr){return;}jclassclazz=nullptr;do{clazz=jniEnv->FindClass("cn/com/codingce/ndkpractice/utils/LogUtils");if(clazz==nullptr){diagnosis_assert(!"FindClassLogUtilserror!");break;}if(jniEnv->RegisterNatives(clazz,nativeUtilsMethods,std::extent::value)!=0){diagnosis_assert(!"RegisterNativeserror!");break;}}while(false);if(jniEnv->ExceptionCheck()==JNI_TRUE){jniEnv->ExceptionClear();}if(clazz!=nullptr){jniEnv->DeleteLocalRef(clazz);}}

【C++】STL梳理

【Android】NDK开发Crash分析

【C++】PK游戏(玩转多态)

以上,便是今天的分享,希望大家喜欢,觉得内容不错的,欢迎「分享」「赞」或者点击「在看」支持,谢谢各位。

关键词: 文件大小 默认名称 输出文件

相关阅读