部分代码如下:
Logger.h代码
// // Created by Administrator on 2021/12/28. // #ifndef EMLIVESDK_LOGGER_H #define EMLIVESDK_LOGGER_H #include#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: static void log(int level , const char * msg , va_list args); 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 #includeLogLevel 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(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(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(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(jniEnv->NewGlobalRef(localClazz));
if(localClazz){
jniEnv->DeleteLocalRef(localClazz);
}
return g_jclazz;
}
return nullptr;
}



