<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【NDK】封裝日志庫(kù)

          共 22596字,需瀏覽 46分鐘

           ·

          2022-12-02 18:35

          點(diǎn)擊關(guān)注,與你共同成長(zhǎng)!




          【NDK】封裝日志庫(kù)

          0x1需求

          • 供C++、Java調(diào)用
          • 控制臺(tái)輸出
          • 文件輸出(文件大?。?/section>
          • 設(shè)置日志等級(jí)

          0x2 C++

          0x21 LogUtils.h

          //
          // Created by 后端碼匠 on 2022/11/30.
          //

          #ifndef NDKPRACTICE_LOGUTILS_H
          #define NDKPRACTICE_LOGUTILS_H


          #include <stdio.h>
          #include <android/log.h>
          #include <errno.h>

          #define  LOG_TAG    "km_media_log"

          #define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,  LOG_TAG, __VA_ARGS__ )
          #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,  LOG_TAG, __VA_ARGS__ )
          #define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,  LOG_TAG, __VA_ARGS__ )
          #define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

          #define LOG_TEXT_MAX_LENGTH        (1024)  //  單條日志大小
          #define LOG_FILE_MAX_SIZE    (1024*1024*3) //  文件最大為3MB

          enum {
              LOG_LEVEL_NONE = 0,
              LOG_LEVEL_ERR = 1,
              LOG_LEVEL_WARNING = 2,
              LOG_LEVEL_INFO = 3,
              LOG_LEVEL_DEBUG = 4
          };

          #ifdef  __cplusplus
          extern "C" {
          #endif

          /**
           * 初始化日志選項(xiàng)
           * @param pFile
           * @param filename
           * @param logLevel
           * @param printScreen
           * @return
           */

          int LogInit(const char *pFile, const char *filename, int logLevel, int printScreen);

          /**
           * 日志處理
           * @param level
           * @param strFormat
           * @param ...
           */

          void WriteTextLog(int level, const char *strFormat, ...);

          /**
           * 向文件中寫(xiě)入日志
           * @param level
           * @param log
           */

          void WriteTextLogBottom(int level, const char *log);

          /**
           * 關(guān)閉日志庫(kù)
           */

          void LogClose();

          #ifdef __cplusplus
          }
          #endif

          #endif //NDKPRACTICE_LOGUTILS_H

          0x22 LogUtils.cpp

          //
          // Created by 后端碼匠 on 2022/11/30.
          //

          #include <cstdio>
          #include <cstdarg>
          #include <ctime>
          #include <sys/stat.h>
          #include <cstring>
          #include <sys/types.h>
          #include <cassert>
          #include <string>
          #include <sstream>
          #include <vector>
          #include <iostream>
          #include <algorithm>
          #include <sys/time.h>
          #include <cstring>
          #include <sys/stat.h>
          #include <dirent.h>
          #include <fcntl.h>

          #include "LogUtils.h"

          char LOG_FILE_NAME[100] = "km_media_log.txt";   //日志默認(rèn)名稱
          // 日志級(jí)別
          int g_log_file_level = LOG_LEVEL_NONE;
          int g_log_screen_level = LOG_LEVEL_NONE;

          long g_RollingPtr = 0;

          // 文件路徑
          static std::string g_logFilePath;

          int LogInit(const char *pFile, const char *filename, int logLevel, int printScreen) {
              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;
              }
              return 0;
          }

          char g_log_info[LOG_TEXT_MAX_LENGTH + 100];

          void WriteTextLog(int level, const char *strFormat, ...) {
              if (level > g_log_file_level && level > g_log_screen_level) {
                  return;
              }
              time_t now;
              char timeStr[20];
              char temBuf[LOG_TEXT_MAX_LENGTH];

              time(&now);
              strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localtime(&now));

              va_list args;
              va_start(args, strFormat);
              vsnprintf(temBuf, sizeof(temBuf) - 1, strFormat, args);
              va_end(args);

              switch (level) {
                  case LOG_LEVEL_DEBUG:
                      LOGD("%s", g_log_info);
                      sprintf(g_log_info, "%s [DEBUG] %s\n", timeStr, temBuf);
                      break;

                  case LOG_LEVEL_INFO:
                      LOGI("%s", g_log_info);
                      sprintf(g_log_info, "%s [INFO] %s\n", timeStr, temBuf);
                      break;

                  case LOG_LEVEL_WARNING:
                      LOGW("%s", g_log_info);
                      sprintf(g_log_info, "%s [WARN] %s\n", timeStr, temBuf);
                      break;

                  case LOG_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);
              }
          }

          void WriteTextLogBottom(int level, const char *log) {
              if (level <= g_log_file_level) {
                  FILE *fp;
                  struct stat info{};
                  if (stat(g_logFilePath.c_str(), &info) != 0) {
                      g_RollingPtr = 0;
                      fp = fopen(g_logFilePath.c_str(), "we"); // create file
                      if (fp == nullptr) {
                          LOGE("%s, fopen(w) %s fail, err:%d", __func__, g_logFilePath.c_str(), errno);
                          return;
                      }
                      fprintf(fp, "%s, stat fail create logfile, errno:%d\n", __func__, errno);
                      fprintf(fp, "%s"log);
                      fclose(fp);
                      return;
                  }

                  if (info.st_size >= LOG_FILE_MAX_SIZE) // loop write
                  {
                      // 這里使用復(fù)寫(xiě)的方式,保證日志文件不會(huì)超過(guò) LOG_FILE_MAX_SIZE
                      fp = fopen(g_logFilePath.c_str(), "r+");

                      if (nullptr == fp) {
                          LOGE("%s, fopen(r+) %s fail, 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) %s fail, size:%ld, err:%d", __func__, g_logFilePath.c_str(),
                               info.st_size, errno);
                          return;
                      }
                  }
                  fprintf(fp, "%s"log);
                  fclose(fp);
              }
          }

          void LogClose() {
              g_log_file_level = LOG_LEVEL_NONE;
              g_log_screen_level = LOG_LEVEL_NONE;
          }

          0x3 Java

          0x31 LogUtils

          //
          // Created by 后端碼匠 on 2022/11/30.
          //

          package cn.com.codingce.ndkpractice.utils;

          import android.content.Context;
          import android.os.Environment;
          import android.util.Log;

          import java.io.File;

          public class LogUtils {

              private static Context globalAplicationContext = null;

              private static String PATH_LOGCAT = null;

              public enum LogLevel {
                  LOG_LEVEL_NONE,
                  LOG_LEVEL_ERR,
                  LOG_LEVEL_WARNING,
                  LOG_LEVEL_INFO,
                  LOG_LEVEL_DEBUG
              }

              public static void init() {

                  if (globalAplicationContext == nullreturn;
                  boolean obtainSDcardAccess = false;
                  try {
                      obtainSDcardAccess = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
                  } catch (Exception e) {
                      Log.e("LogUtils""Exception: " + e.getMessage());
                  }
                  if (obtainSDcardAccess) {// 優(yōu)先保存到SD卡中
                      final File externalFilesDir = globalAplicationContext.getExternalFilesDir(null);
                      if (externalFilesDir != null) {
                          PATH_LOGCAT = externalFilesDir.getAbsolutePath() + File.separator + "kmsdk";
                      } else {// 如果SD卡不存在,就保存到本應(yīng)用的目錄下
                          PATH_LOGCAT = globalAplicationContext.getFilesDir().getAbsolutePath()
                                  + File.separator + "kmsdk";
                      }
                  } else {// 如果SD卡不存在,就保存到本應(yīng)用的目錄下
                      PATH_LOGCAT = globalAplicationContext.getFilesDir().getAbsolutePath()
                              + File.separator + "kmsdk";
                  }

                  File file = new File(PATH_LOGCAT);
                  if (!file.exists()) {
                      file.mkdirs();
                  }
                  LogInit(PATH_LOGCAT, "km_media_log.txt"44);
                  Log.e("LogUtils""cur file dir is:" + file.toString());
              }

              public synchronized static void setApplicationContext(Context aplicationContext) {
                  globalAplicationContext = aplicationContext.getApplicationContext();
              }

              // 日志類(lèi)初始化
              public static native void LogInit(String logFilePath, String logName, int logfileLevel, int logScreenLevel);

              public static native void logJni(int logLevel, String content);

              public static native void logClose();

          }

          0x32 Native

          //
          // Created by 后端碼匠 on 2022/11/30.
          //

          #include <jni.h>
          #include <string>
          #include "LogUtils.h"

          #define diagnosis_assert(...) assert(__VA_ARGS__)

          int ret = -1;
          static void nativeLogUtilsRegisterNatives(JNIEnv *jniEnv);

          JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
              JNIEnv *jniEnv{nullptr};
              if (vm->GetEnv((void **) &jniEnv, JNI_VERSION_1_6) != JNI_OK) {
                  diagnosis_assert(!"JNI version error!");
                  return JNI_EVERSION;
              }

              nativeLogUtilsRegisterNatives(jniEnv);
              return JNI_VERSION_1_6;
          }

          static void LocalLogInit(JNIEnv *env, jclass clazz,
                                   jstring logFilePath, jstring logName,
                                   jint logfile_level, jint log_screen_level)
           
          {
              if (ret != 0) {
                  const char *path = env->GetStringUTFChars(logFilePath, JNI_FALSE);
                  const char *name = env->GetStringUTFChars(logName, JNI_FALSE);
                  int fileLevel = logfile_level;
                  int screenLevel = log_screen_level;
                  ret = LogInit(path, name, fileLevel, screenLevel);
                  env->ReleaseStringUTFChars(logFilePath, path);
                  env->ReleaseStringUTFChars(logName, name);
              }
          }


          static void logJni(JNIEnv *env, jclass clazz, jint _level,
                             jstring _str)
           
          {
              if (ret != 0) {
                  LOGE("log error! LogInit need");
                  return;
              }
              const char *str = env->GetStringUTFChars(_str, JNI_FALSE);
              WriteTextLog(_level, str);
              env->ReleaseStringUTFChars(_str, str);
          }

          static void logClose(JNIEnv *env, jclass clazz) {
              LogClose();
              ret = -1;
          }

          static JNINativeMethod nativeUtilsMethods[] = {
                  {"LogInit",  "(Ljava/lang/String;Ljava/lang/String;II)V", (void *) LocalLogInit},
                  {"logJni",   "(ILjava/lang/String;)V",                    (void *) logJni},
                  {"logClose""()V",                                       (void *) logClose},
          };

          static void nativeLogUtilsRegisterNatives(JNIEnv *jniEnv) {
              if (jniEnv == nullptr) {
                  return;
              }

              jclass clazz = nullptr;
              do {
                  clazz = jniEnv->FindClass("cn/com/codingce/ndkpractice/utils/LogUtils");
                  if (clazz == nullptr) {
                      diagnosis_assert(!"FindClass LogUtils error!");
                      break;
                  }
                  if (jniEnv->RegisterNatives(clazz, nativeUtilsMethods,
                                              std::extent<decltype(nativeUtilsMethods)>::value) != 0) {
                      diagnosis_assert(!"RegisterNatives error!");
                      break;
                  }
              } while (false);
              if (jniEnv->ExceptionCheck() == JNI_TRUE) {
                  jniEnv->ExceptionClear();
              }
              if (clazz != nullptr) {
                  jniEnv->DeleteLocalRef(clazz);
              }
          }




          【C++】STL梳理

          【Android】NDK開(kāi)發(fā)Crash分析

          【C++】PK游戲(玩轉(zhuǎn)多態(tài))


          以上,便是今天的分享,希望大家喜歡,覺(jué)得內(nèi)容不錯(cuò)的,歡迎「分享」「」或者點(diǎn)擊「在看」支持,謝謝各位。

          瀏覽 74
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男操女逼射逼心国产中字传媒视频 | 超碰 天天干 天天摸 | 黄片国产在线观看 | 影音先锋成人电影在线播放 | 欧美A片在线视频 |