目錄
6、 Android UI 單線程程序
單線程程序概念
單線程可避免線程安全問題
SurfaceView與非UI線程
6、 Android UI 單線程程序
單線程程序概念
- 單線程程序意謂著兩個(或多個)線程不能共享對象或變量值。
- Android的UI是單線程程序的環境。
- UI控件(如Button等)都是由UI線程所創建,內部攸關于UI顯示的屬性或變量都只有UI線程才能存取(Access)之,別的線程并不能去存取之。
- 例如下圖里的View類別體系,都只限于UI線程才能去執行它們的onDraw()函數,因為它會實際更動到UI的屬性。
- 由于UI線程來執行onCreate()函數,誕生了Button對象,因而只限UI線程能去存取該對象里攸關UI的屬性,其它線程不能去碰它們。
單線程可避免線程安全問題
- 線程安全問題就是如何避免不同線程之間,可能會相互干擾的問題。
- 雖然兩個線程幾乎同時先后執行一個類別里的(可能不同)函數,只要不共享對象、或共享變量(例如Android的UI單線程環境),就不會產生干擾現象,也就沒有線程安全問題。
- 換句話說,如果各自使用自己的對象或變量(即不共享對象或變量),就不會干擾到別線程執行的正確性了。
- 例如下述范例:
// Ex01.java class Task2{private int count;public void init(){ count = 0; }public void f1() {for(int i=0; i<3; i++) {count++;try {Thread.sleep(10);} catch (InterruptedException e) { e.printStackTrace(); }System.out.println(Thread.currentThread().getName() +"'s count: " + count);}} }class Task implements Runnable {public void run() {Task2 ta2 = new Task2();ta2.init(); ta2.f1();} }public class JMain {public static void main(String[] args) {Task ta = new Task();Thread t1 = new Thread( ta, "A");Thread t2 = new Thread( ta, "B");t1.start();t2.start();System.out.println("Waiting...");} }
這里, t1和t2線程共享主線程所誕生的ta對象,但是各自誕生了Task2類別之對象。兩者各自使用自己的對象(即不共享對象或變量),就不會干擾到別線程的數據。所以輸出正確的結果:
? ? ? ? ?Waiting...
? ? ? ? ? ? B's count: 1
? ? ? ? ? ? A's count: 1
? ? ? ? ? ?B's count: 2
? ? ? ? ? ?A's count: 2
? ? ? ? ? ?B's count: 3
? ? ? ? ? ?A's count: 3
SurfaceView與非UI線程
- View控件是由UI 線程(主線程)所執行。如果需要去迅速更新UI畫面或者UI畫圖需要較長時間(避免阻塞主線程),就使用SurfaceView。
- 它可以由背景線程(background thead)來執行,而View只能由UI(主)線程執行畫面顯示或更新。
- 在SurfaceView里,非UI線程可以去碰觸UI顯示,例如將圖形繪制于Surface畫布上。這SurfaceView內含高效率的rendering機制,能讓背景線程快速更新surface的內容,適合演示動畫(animation)。