部分代码如下:
Logger.h代码
//
// Created by Administrator on 2021/12/28.
//
#ifndef EMLIVESDK_LOGGER_H
#define EMLIVESDK_LOGGER_H
#include <stdarg.h>
#define Logv( msg , ...) log(Log_Level_V , msg , ##__VA_ARGS__);
#define Logd( msg , ...) log(Log_Level_D , msg , ##__VA_ARGS__);
#define Logi( msg , ...) log(Log_Level_I , msg , ##__VA_ARGS__);
#define Logw( msg , ...) log(Log_Level_W , msg , ##__VA_ARGS__);
#define Loge( msg , ...) log(Log_Level_E , msg , ##__VA_ARGS__);
typedef void (*androidLog)(int level , char * msg) ;
enum LogLevel{
Log_Level_V = 1,
Log_Level_D,
Log_Level_I,
Log_Level_W,
Log_Level_E,
};
class Logger{
public:
/**
* 日志回调
*
* 非线程安全的,所以一般在jni load的时候初始化
*
* @param level 日志等级
* @param msg 日志内容
* @param args 日志内容的占位参数值
*/
static void log(int level , const char * msg , va_list args);
/**
* 初始化log回调
* @param logCb 全局日志的回调函数
* @param level 全局的日志等级
*/
static void initLog(androidLog logCb , LogLevel level);
private :
static androidLog g_LogCb;
static LogLevel g_LogLevel;
};
void log(int level , const char * msg , ...);
#endif //EMLIVESDK_LOGGER_H
Logger.cpp代码
//
// Created by Administrator on 2021/12/29.
//
#include "Logger.h"
#include <android/log.h>
#include <stdio.h>
LogLevel Logger::g_LogLevel = Log_Level_V;
androidLog Logger::g_LogCb = 0;
void Logger::initLog(androidLog logCb , LogLevel level){
g_LogCb = logCb;
g_LogLevel = level;
}
void Logger::log(int level , const char * msg , va_list args){
if(level < g_LogLevel){
return;
}
if(g_LogCb){
char msgBuffer[800] = {0};
vsnprintf(msgBuffer, sizeof(msgBuffer) - 1 , msg, args);
g_LogCb(level , msgBuffer);
}else{
int androidLogLevel;
switch (level) {
case Log_Level_V:
androidLogLevel = ANDROID_LOG_VERBOSE;
break;
case Log_Level_D:
androidLogLevel = ANDROID_LOG_DEBUG;
break;
case Log_Level_I:
androidLogLevel = ANDROID_LOG_INFO;
break;
case Log_Level_W:
androidLogLevel = ANDROID_LOG_WARN;
break;
case Log_Level_E:
androidLogLevel = ANDROID_LOG_ERROR;
break;
}
__android_log_print(androidLogLevel, "EMLogger", msg , args);
}
}
void log(int level, const char *msg, ...) {
va_list args;
va_start(args , msg);
Logger::log(level , msg , args);
va_end(args);
}
JniHelper.h
//
// Created by Administrator on 2021/12/27.
//
#ifndef EMLIVESDK_JNIHELPER_H
#define EMLIVESDK_JNIHELPER_H
#include "jni.h"
#include "pthread.h"
class JniHelper {
public:
static void initJVM(JavaVM* vm);
static JNIEnv * getEnv();
static jclass findGClass(const char * name);
static jclass findGClass(JNIEnv * env , const char * name);
private:
static void pthread_once_method();
static void destroyKey(void * value);
private:
static JavaVM* sJavaVm;
static pthread_key_t pthreadKey;
static pthread_once_t pthreadOnce;
};
#endif //EMLIVESDK_JNIHELPER_H
JniHelper.cpp
//
// Created by Administrator on 2021/12/27.
//
#include "JniHelper.h"
#include "Logger.h"
JavaVM * JniHelper::sJavaVm = nullptr;
pthread_key_t JniHelper::pthreadKey = 0;
pthread_once_t JniHelper::pthreadOnce = PTHREAD_ONCE_INIT;
void JniHelper::initJVM(JavaVM *vm) {
sJavaVm = vm;
}
JNIEnv *JniHelper::getEnv() {
JavaVM * javaVm = sJavaVm;
pthread_once(&pthreadOnce , JniHelper::pthread_once_method);//进程中只执行一次,创建key,注意这里第一个参数必须是PTHREAD_ONCE_INIT
JNIEnv * jniEnv = static_cast<JNIEnv *>(pthread_getspecific(pthreadKey));//所有线程共享key,但是各个线程有自己的数据存储区
if(!jniEnv){
if(javaVm && javaVm->AttachCurrentThread(&jniEnv , nullptr) == JNI_OK){
pthread_setspecific(pthreadKey , jniEnv);//设置自己线程参数
Logd("AttachCurrentThread lxs1230 %u" , pthread_self())
}
}
return jniEnv;
}
void JniHelper::pthread_once_method() {
pthread_key_create(&pthreadKey , JniHelper::destroyKey);
}
void JniHelper::destroyKey(void * value) {
JNIEnv * jniEnv = static_cast<JNIEnv *>(value);
if(jniEnv){
// Logd("DetachCurrentThread lxs1230 %u" , pthread_self())//这里位置不要放到DetachCurrentThread后面,
JavaVM * javaVm = sJavaVm;
pthread_setspecific(pthreadKey , nullptr);
javaVm->DetachCurrentThread();
}
}
jclass JniHelper::findGClass(const char * name) {
JNIEnv * jniEnv = JniHelper::getEnv();
if(jniEnv){
jclass localClazz = jniEnv->FindClass(name);
jclass g_jclazz = static_cast<jclass>(jniEnv->NewGlobalRef(localClazz));
if(localClazz){
jniEnv->DeleteLocalRef(localClazz);
}
return g_jclazz;
}
return nullptr;
}
jclass JniHelper::findGClass(JNIEnv *jniEnv, const char *name) {
if(jniEnv){
jclass localClazz = jniEnv->FindClass(name);
jclass g_jclazz = static_cast<jclass>(jniEnv->NewGlobalRef(localClazz));
if(localClazz){
jniEnv->DeleteLocalRef(localClazz);
}
return g_jclazz;
}
return nullptr;
}