// watch all runnable which post in main threadclass MainLooperWatcher : Printer {privateval TAG ="MainLooperWatcher"privatevar mLastMillis: Long =0privatevar mLastSeconds: Long =0privatevar mTimesPerSeconds: Long =0funmainThreadWatcher(){
Looper.getMainLooper().setMessageLogging(this)}overridefunprintln(msg: String?){// ignore system taskif(msg ==null|| TextUtils.isEmpty(msg)|| msg.contains("Choreographer")|| msg.contains("ActivityThread\$H"))returnif(msg.startsWith(">>>>> Dispatching")){
mLastMillis = SystemClock.elapsedRealtime()
mTimesPerSeconds++if( mTimesPerSeconds >100){report(msg,0, mTimesPerSeconds)}if(mLastMillis - mLastSeconds >1000){
mLastSeconds = mLastMillis
mTimesPerSeconds =0}}else{// <<<<< Finishedval now = SystemClock.elapsedRealtime()val usedMillis = now - mLastMillis
if(usedMillis <16L)returnif(usedMillis >48){
Log.w(TAG,"$usedMillis ms used for $msg, $mLastSeconds")}else{
Log.i(TAG,"$usedMillis ms used for $msg, $mLastSeconds")}if(usedMillis >500L){report(msg, usedMillis, mTimesPerSeconds)
mTimesPerSeconds =0}}}privatefunreport(msg: String, usedMillis: Long, callsInSecond: Long){val sb =StringBuilder()
Looper.getMainLooper().dump(StringBuilderPrinter(sb),"")
Lg.e(TAG,"$usedMillis ms used for $msg, $mLastSeconds", sb)val exp ="[Block Runnable] ${usedMillis}ms used for ${msg}, $callsInSecond calls in one seconds"
Lg.e(TAG, exp)if(Debug.isDebuggerConnected()|| Debug.waitingForDebugger())returnif(BuildConfig.DEBUG && usedMillis >4000){throwRuntimeException(exp)}else{// TOAST}}}// MainLooperWatcher().mainThreadWatcher()