ndk实例总结:jni日志存储

ndk实例总结

ndk实例总结:jni实例
ndk实例总结:opencv图像处理
ndk实例总结:安卓Camera与usbCamera原始图像处理
ndk实例总结补充:使用V4L2采集usb图像分析
ndk实例总结:使用fmpeg播放rtsp流
ndk实例总结:基于libuvc的双usbCamera处理
ndk实例总结补充:使用libuvc采集usb图像分析
ndk实例总结:jni日志存储

前言

本文是jni日志存储的实例,能够同时将jni日志打印在logcat中并且保存到日志文件内

代码

namespace jlog {
    namespace {
        const static size_t buf_length = 2048;
        static char log_buf[buf_length];
    }
    static std::ofstream log_of_stream;
    static std::atomic_bool save_log{false};

    static void logOutput(const std::string &s) {
        if (!save_log) return;

        //---------------
        // M-Thread support
        //---------------
#if NO_STD_THREAD
#else
        static std::mutex log_mutex;
        std::unique_lock<std::mutex> lock(log_mutex);
#endif
        //------
        std::cout << s << std::endl;
        //---- Set log file
        if (log_of_stream.is_open()) {
            log_of_stream << (s + "\n");
            log_of_stream.flush();
        }
    }

    static void logMsg(const std::string &sTag, const std::string &sMsg) {
        time_t now;
        time(&now);
        char timeStr[20];
        strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localtime(&now));
        logOutput(std::string(timeStr) + " [" + sTag + "]: " + sMsg);
    }

    extern void logVerbose(const std::string &s) {
        logMsg("Verbose", s);
    }

    extern void logDebug(const std::string &s) {
        logMsg("Debug", s);
    }

    extern void logInfo(const std::string &s) {
        logMsg("Info", s);
    }

    extern void logError(const std::string &s) {
        logMsg("Error", s);
    }

    extern void logWarn(const std::string &s) {
        logMsg("Warn", s);
    }

    extern void logFatal(const std::string &s) {
        logMsg("Fatal", s);
    }

    extern void logFileErr(const std::string &sFile) {
        logError(std::string("Fail to open file [") + sFile + "]");
    }

    extern bool initLog(const std::string &sFileLog) {
        auto &ofs = log_of_stream;
        auto mode = std::ofstream::out;
        int append = true;
        if (append) mode |= std::ofstream::app;
        ofs.open(sFileLog, mode);
        if (!ofs.is_open()) {
            logFileErr(sFileLog);
            return false;
        }
        save_log = true;
        return true;
    }

    extern bool closeLog() {
        save_log = true;
        auto &ofs = log_of_stream;
        ofs.close();
        return true;
    }
}

#define  LOG_TAG    "jlog"

#define LOG2BUF(...)  \
    { std::snprintf(jlog::log_buf, 2048, __VA_ARGS__); }
#define BUF2FILE(FUNC) \
    {FUNC(std::string(LOG_TAG)+":"+std::string(jlog::log_buf));}

#define _LOGV(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logVerbose); }
#define _LOGD(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logDebug); }
#define _LOGI(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logInfo); }
#define _LOGW(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logWarn); }
#define _LOGE(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logError); }
#define _LOGF(...) { LOG2BUF(__VA_ARGS__); BUF2FILE(jlog::logFatal); }

#define  LOGV(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGV(__VA_ARGS__);}
#define  LOGD(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGD(__VA_ARGS__);}
#define  LOGI(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGI(__VA_ARGS__);}
#define  LOGW(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGW(__VA_ARGS__);}
#define  LOGE(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGE(__VA_ARGS__);}
#define  LOGF(...)  {__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);_LOGF(__VA_ARGS__);}

说一下原理,主要是定义了多种宏,__android_log_print会直接打印到logcat中,_LOGI会保存到文件中

_LOGI宏会调用LOG2BUF与BUF2FILE,顾名思义第一个将日志存在内存buff中,第二个将buff通过ofstream写到文件里

使用方式

初始化

extern "C"
JNIEXPORT void JNICALL
Java_com_gavinandre_nativeloglibrary_JLogLib_initLog(
        JNIEnv *env, jclass clazz, jstring log_path) {
    const char *c = env->GetStringUTFChars(log_path, JNI_FALSE);
    std::string c_path = std::string(c);
    jlog::initLog(c_path);
}

保存日志

extern "C"
JNIEXPORT void JNICALL
Java_com_gavinandre_nativeloglibrary_JLogLib_logFromNative(
        JNIEnv *env, jclass clazz) {
    LOGI("jlog log from native");
    LOGE("jlog log from native");
}

关闭

extern "C"
JNIEXPORT void JNICALL
Java_com_gavinandre_nativeloglibrary_JLogLib_closeLog(
        JNIEnv *env, jclass clazz) {
    jlog::closeLog();
}

最后完整代码可以参考demo

ndk开发基础学习系列

JNI和NDK编程(一)JNI的开发流程
JNI和NDK编程(二)NDK的开发流程
JNI和NDK编程(三)JNI的数据类型和类型签名
JNI和NDK编程(四)JNI调用Java方法的流程

完整demo

https://github.com/GavinAndre/AndroidJNIDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值