为什么UI线程中创建Handler可以不传Looper?
生活随笔
收集整理的這篇文章主要介紹了
为什么UI线程中创建Handler可以不传Looper?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一個APP程序的入口是ActivityThread的main方法,ActivityThread就是我們常說的主線程或UI線程,事實上它并不是一個線程,而是主線程操作的管理者。
public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());AndroidKeyStoreProvider.install();// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");//給主線程設置一個Looper實例Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();//此方法會完成Application對象的初始化,//然后調用Application的onCreate()方法thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);//啟動消息輪詢Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");
}
主要方法是Looper.prepareMainLooper(),給主線程設置一個Looper實例
public static void prepareMainLooper() {//創建一個Looper實例,將此對象實例存到ThreadLocal的實例中prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}//sMainLooper就是Looper實例,//myLooper()方法會從ThreadLocal中獲取Looper實例sMainLooper = myLooper();}
}
Looper類的prepare()方法,創建一個Looper實例,將值存到ThreadLocal的實例中
private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}//給ThreadLocal設置一個Looper對象sThreadLocal.set(new Looper(quitAllowed));
}
下面是Looper類的myLooper()方法,很簡單的
public static @Nullable Looper myLooper() {return sThreadLocal.get();
}
再看Handler的無參構造方法,我們在主線程中就是直接用New Handler()創建其實例
public Handler() {this(null, false);
}public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}//獲取Looper實例mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;
}
在其重載構造方法中, mLooper = Looper.myLooper(),從ThreadLocal中獲取Looper實例,這就解釋了在主線程中構建Handler不需要傳Looper的原因,構造方法會自己去獲取。
總結
以上是生活随笔為你收集整理的为什么UI线程中创建Handler可以不传Looper?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ViewGroup的Touch事件分发(
- 下一篇: Android报错:java.lang.