代码实现
import android. app. Application
import android. content. Context
import android. os. Handler
import android. os. Looper
import android. util. Log
import java. lang. Exception
class MyApplication : Application ( ) {
override fun attachBaseContext ( base: Context? ) {
super . attachBaseContext ( base)
}
override fun onCreate ( ) {
super . onCreate ( )
Thread. setDefaultUncaughtExceptionHandler {
t, e ->
Log. d ( "xxx" , "thread::${
t. name} ;;${
e. message} " )
e. printStackTrace ( )
errorHandler ( )
}
Handler ( Looper. getMainLooper ( ) ) . post {
while ( true ) {
try {
Looper. loop ( )
} catch ( e: Exception) {
Log. d ( "xxx" , "${
e. message} " )
e. printStackTrace ( )
errorHandler ( )
}
}
}
}
private fun errorHandler ( ) {
}
}
Handler(Looper.getMainLooper()).post () 方案 原理
在 Android 中 ActivityThread 的源码中的loop方法中分发 主线程的 队列消息 ,源代码如下
for ( ; ; ) {
Message msg = queue. next ( ) ;
if ( msg == null) {
return ;
}
final Printer logging = me. mLogging;
if ( logging != null) {
logging. println ( ">>>>> Dispatching to " + msg. target + " " +
msg. callback + ": " + msg. what) ;
}
final Observer observer = sObserver;
final long traceTag = me. mTraceTag;
long slowDispatchThresholdMs = me. mSlowDispatchThresholdMs;
long slowDeliveryThresholdMs = me. mSlowDeliveryThresholdMs;
if ( thresholdOverride > 0 ) {
slowDispatchThresholdMs = thresholdOverride;
slowDeliveryThresholdMs = thresholdOverride;
}
final boolean logSlowDelivery = ( slowDeliveryThresholdMs > 0 ) && ( msg. when > 0 ) ;
final boolean logSlowDispatch = ( slowDispatchThresholdMs > 0 ) ;
final boolean needStartTime = logSlowDelivery || logSlowDispatch;
final boolean needEndTime = logSlowDispatch;
if ( traceTag != 0 && Trace. isTagEnabled ( traceTag) ) {
Trace. traceBegin ( traceTag, msg. target. getTraceName ( msg) ) ;
}
final long dispatchStart = needStartTime ? SystemClock. uptimeMillis ( ) : 0 ;
final long dispatchEnd;
Object token = null;
if ( observer != null) {
token = observer. messageDispatchStarting ( ) ;
}
long origWorkSource = ThreadLocalWorkSource. setUid ( msg. workSourceUid) ;
try {
msg. target. dispatchMessage ( msg) ;
if ( observer != null) {
observer. messageDispatched ( token, msg) ;
}
dispatchEnd = needEndTime ? SystemClock. uptimeMillis ( ) : 0 ;
} catch ( Exception exception) {
if ( observer != null) {
observer. dispatchingThrewException ( token, msg, exception) ;
}
throw exception;
} finally {
ThreadLocalWorkSource. restore ( origWorkSource) ;
if ( traceTag != 0 ) {
Trace. traceEnd ( traceTag) ;
}
}
if ( logSlowDelivery) {
if ( slowDeliveryDetected) {
if ( ( dispatchStart - msg. when) <= 10 ) {
Slog. w ( TAG, "Drained" ) ;
slowDeliveryDetected = false ;
}
} else {
if ( showSlowLog ( slowDeliveryThresholdMs, msg. when, dispatchStart, "delivery" ,
msg) ) {
slowDeliveryDetected = true ;
}
}
}
if ( logSlowDispatch) {
showSlowLog ( slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch" , msg) ;
}
if ( logging != null) {
logging. println ( "<<<<< Finished to " + msg. target + " " + msg. callback) ;
}
final long newIdent = Binder. clearCallingIdentity ( ) ;
if ( ident != newIdent) {
Log. wtf ( TAG, "Thread identity changed from 0x"
+ Long. toHexString ( ident) + " to 0x"
+ Long. toHexString ( newIdent) + " while dispatching to "
+ msg. target. getClass ( ) . getName ( ) + " "
+ msg. callback + " what=" + msg. what) ;
}
msg. recycleUnchecked ( ) ;
}
我们现在的这种做法相当于 将 上述代码分割线一下的代码替换成了 post()函数闭包里面的代码,即:
for ( ; ; ) {
Message msg = queue. next ( ) ;
if ( msg == null) {
return ;
}
while ( true ) {
try {
Looper. loop ( )
} catch ( Exception e ) {
Log. d ( "xxx" , "${e.message}" )
e. printStackTrace ( )
errorHandler ( )
}
}
}