1. 程式人生 > 其它 >Android 非UI執行緒不能更新UI

Android 非UI執行緒不能更新UI

1. 什麼是UI執行緒?

  App通過Zygote fork建立一個App程序,通過ActivityThread的main()函式建立ActivityThread例項及UI執行緒Looper物件。

  程式都有一個main()函式,也就是主函式,Android中的主函式在ActivityThread這個類中,主函式是一個靜態方法。

  原始碼:

public class ActivityThread {
    ...

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 
"ActivityThreadMain"); // Install selective syscall interception AndroidOs.install(); // 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(); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0(
"<pre-initialized>"); Looper.prepareMainLooper(); // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. // It will be in the format "seq=114" long startSeq = 0; if (args != null) { for (int i = args.length - 1; i >= 0; --i) { if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { startSeq = Long.parseLong( args[i].substring(PROC_START_SEQ_IDENT.length())); } } } ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(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程式碼是一樣的。

  UI執行緒就是通過AMS Zygeto fork建立程序時建立的執行緒主執行緒就是UI執行緒。

2. 主執行緒是如何工作的?

  就是Handler原理,典型的生產者消費者模式;

3. 假設,把UI執行緒設計成執行緒安全的?

  1.什麼是執行緒不安全?

  可變資源(記憶體)執行緒間共享。

  2. 如果多執行緒更新TextView,執行緒安全就是設計成這樣:

  圖上可知就是加鎖,加鎖是比較耗時的,但是,UI更新又是一個高頻更新。

  3. 為什麼不設計成執行緒安全?

    1. UI具有可變性,甚至是高頻可變性;

    2. UI對響應時間敏感性的要求UI操作必須高效;

    3. UI元件必須批量繪製來保住效率;

4. 非UI執行緒就一定不能更新UI嗎?

  1. 工作執行緒間接更新UI,比如:網路請求:

  正常通知UI執行緒更新UI:

  工作執行緒(I/O執行緒)間接更新UI:

  2. 工作執行緒直接更新UI,比如:SurfaceView就是子執行緒更新渲染的:

  視訊畫面渲染顯示就是使用SurfaceView。

  地圖使用的是GLSurfaceView,是SurfaceView子類,GLSurfaceView是OpenGL渲染。