1.LoopMonitor开启单独线程每隔1s监听一次
abstract class LoopMonitor<C> : Monitor<C>(), Callable<LoopMonitor.LoopState> {
companion object {
private const val DEFAULT_LOOP_INTERVAL = 1000L
}
//是否停止了
//https://www.jianshu.com/p/3963e64e7fe7
//在kotlin中没有volatile关键字,但是有@Volatile注解,
@Volatile//@Volatile将把JVM支持字段标记为volatile
private var mIsLoopStopped = true
//单独线程
private val mLoopRunnable = object : Runnable {
override fun run() {
//如果call返回Terminate则停止
if (call() == LoopState.Terminate) {
return
}
if (mIsLoopStopped) {
return
}
getLoopHandler().removeCallbacks(this)
getLoopHandler().postDelayed(this, getLoopInterval())
}
}
//开启
open fun startLoop(
clearQueue: Boolean = true,
postAtFront: Boolean = false,
delayMillis: Long = 0L
) {
if (clearQueue) getLoopHandler().removeCallbacks(mLoopRunnable)
if (postAtFront) {
getLoopHandler().postAtFrontOfQueue(mLoopRunnable)
} else {
getLoopHandler().postDelayed(mLoopRunnable, delayMillis)
}
mIsLoopStopped = false
}
//停止
open fun stopLoop() {
mIsLoopStopped = true
getLoopHandler().removeCallbacks(mLoopRunnable)
}
//1s中
protected open fun getLoopInterval(): Long {
return DEFAULT_LOOP_INTERVAL
}
//一个开启消息循环线程的Handler
protected open fun getLoopHandler(): Handler {
return commonConfig.loopHandlerInvoker()
}
sealed class LoopState {
//两个状态Continue
object Continue : LoopState()
//两个状态Terminate
object Terminate : LoopState()
}
}
2.LoopThread开辟单独线程
//用object 修饰的类为静态类,里面的方法和变量都为静态的。
internal object LoopThread : HandlerThread("LoopThread", THREAD_PRIORITY_BACKGROUND) {
init {
start()
}
internal val LOOP_HANDLER = Handler(LoopThread.looper)
}
3.CommonConfig默认文件夹,SharedPreferences,log,线程池等
class CommonConfig private constructor(
// MonitorManager common properties
val application: Application,
// Custom FileManager or sharedPreferences
val rootFileInvoker: (String) -> File,//默认文件夹
val sharedPreferencesInvoker: (String) -> SharedPreferences,
val sharedPreferencesKeysInvoker: (SharedPreferences) -> Set<String>,
// MonitorBuildConfig common properties
internal val debugMode: Boolean,
internal val versionNameInvoker: () -> String,
internal val logger: Logger, //koom的Logger
internal val log: Log, //koom的Log
// toolbox
internal val loadSoInvoker: (String) -> Unit,
internal val executorServiceInvoker: (() -> ExecutorService)?,//线程池
// For LooperMonitor
internal val loopHandlerInvoker: () -> Handler
) {
class Builder {
private lateinit var mApplication: Application
private var mDebugMode = true
private lateinit var mVersionNameInvoker: () -> String
private lateinit var mDeviceIdInvoker: (() -> String)
private var mRootFileInvoker: ((String) -> File)? = null
private var mSharedPreferencesInvoker: ((String) -> SharedPreferences)? = null
private var mSharedPreferencesKeysInvoker: ((SharedPreferences) -> Set<String>)? = null
private var mLogger: Logger? = null
private var mLog: Log? = null
private var mLoadSoInvoker: ((String) -> Unit)? = null
private var mExecutorServiceInvoker: (() -> ExecutorService)? = null
private var mLoopHandlerInvoker: (() -> Handler)? = null
fun setApplication(application: Application) = apply {
mApplication = application
}
fun setDebugMode(debugMode: Boolean) = apply {
mDebugMode = debugMode
}
fun setVersionNameInvoker(versionNameInvoker: () -> String) = apply {
mVersionNameInvoker = versionNameInvoker
}
fun setRootFileInvoker(rootFileInvoker: (String) -> File) = apply {
mRootFileInvoker = rootFileInvoker
}
fun setSharedPreferencesInvoker(sharedPreferencesInvoker: (String) -> SharedPreferences) = apply {
mSharedPreferencesInvoker = sharedPreferencesInvoker
}
fun setSharedPreferencesKeysInvoker(
sharedPreferencesKeysInvoker: (SharedPreferences) -> Set<String>
) = apply {
mSharedPreferencesKeysInvoker = sharedPreferencesKeysInvoker
}
fun setLoadSoInvoker(LoadSoInvoker: (String) -> Unit) = apply {
mLoadSoInvoker = LoadSoInvoker
}
fun setLogger(logger: Logger) = apply {
mLogger = logger
}
fun setLog(log: Log) = apply {
mLog = log
}
fun setExecutorServiceInvoker(executorServiceInvoker: () -> ExecutorService) = apply {
mExecutorServiceInvoker = executorServiceInvoker
}
fun setLoopHandlerInvoker(loopHandlerInvoker: () -> Handler) = apply {
mLoopHandlerInvoker = loopHandlerInvoker
}
fun build(): CommonConfig = CommonConfig(
application = mApplication,
debugMode = mDebugMode,
versionNameInvoker = mVersionNameInvoker,
rootFileInvoker = mRootFileInvoker ?: {//默认文件夹
//https://blog.csdn.net/Kelaker/article/details/80471352
//内部存储:应用文件目录:$applicationDir/files
//外部存储:应用文件目录:$applicationDir/files,
// 通过Context.getExternalFilesDir(String type),type为空字符串时获取。
val rootDir = runCatching { mApplication.getExternalFilesDir("") }.getOrNull()
//rootDir不为努力了,则parent为rootDir,否则为mApplication.filesDir
File(rootDir ?: mApplication.filesDir, "performance/$it")
.apply { mkdirs() }
},
sharedPreferencesInvoker = mSharedPreferencesInvoker ?: {
mApplication.getSharedPreferences("performance", Context.MODE_PRIVATE)//默认performance
},
sharedPreferencesKeysInvoker = mSharedPreferencesKeysInvoker ?: { it.all.keys },
logger = mLogger ?: object : Logger {},
log = mLog ?: object : Log {},
loadSoInvoker = mLoadSoInvoker ?: { System.loadLibrary(it) },
executorServiceInvoker = mExecutorServiceInvoker,
loopHandlerInvoker = mLoopHandlerInvoker ?: { LoopThread.LOOP_HANDLER }//默认LoopThread.LOOP_HANDLER
)
}
}
4.Monitor 一个CommonConfig公共配置,一个单独配置
abstract class Monitor<C> {
//一个CommonConfig公共配置
private var _commonConfig: CommonConfig? = null
protected val commonConfig: CommonConfig
get() = _commonConfig!!
//一个c,单独配置
private var _monitorConfig: C? = null
protected val monitorConfig: C
get() = _monitorConfig!!
//是否初始化了
open var isInitialized = false
protected inline fun throwIfNotInitialized(
onDebug: () -> Unit = {
throw RuntimeException("Monitor is not initialized")
},
onRelease: () -> Unit
) {
if (isInitialized) {
return
}
if (MonitorBuildConfig.DEBUG) {
onDebug()
} else {
onRelease()
}
}
protected fun Boolean.syncToInitialized() = apply {
isInitialized = this && isInitialized
}
open fun init(commonConfig: CommonConfig, monitorConfig: C) {
_commonConfig = commonConfig
_monitorConfig = monitorConfig
isInitialized = true
}
open fun getLogParams(): Map<String, Any> {
return mapOf("${javaClass.simpleName.decapitalize()}ingEnabled" to isInitialized)
}
}