一起學Android之Handler,簡單介紹Handler的相關知識點以及初步應用,僅供學習分享使用。 ...
概述
在Android開發中,有主線程(UI線程)和工作線程(Worker線程)之分,兩個線程是相互獨立的,並不能相互訪問(主線程主要負責UI的更新,不能進行耗時的操作,工作線程主要負責耗時的操作,但不能進行UI的更新),所以要在兩個線程之間進行數據傳遞,就需要Handler作為傳遞數據的橋梁。每一個Handler對象,都與獨立的線程以及線程的消息隊列有關。本文僅供學習分享使用。
Handler邏輯
- Looper會從消息隊列中,將消息對象取出。
- Looper會找到Message對象對應的Handler對象。
- Looper會調用Handler對象的handleMessage方法,用於處理對象。
涉及知識點
- Android線程:有主線程(UI線程)和工作線程(Worker線程)
- Handler 允許發送和處理與線程相關的消息對列的可運行對象。
- handleMessage (Message msg) 必須在子類進行重寫的的處理消息的方法。
- sendMessage (Message msg) 發送消息方法。
- obtainMessage () 用於從全局消息池中獲取一個新的對象。
- Message 定義一個用於描述和任意數據對象的消息,此消息可以發送到Handler對象。
- what 消息對象的標識符。
- arg1,arg2 用於存儲整型數據的值。
- obj 可以接受任意的對象,用於存儲消息的對象的值。
- Thread 線程是一個可併發執行的單元。重寫run方法來處理線程內容。
Handler原理
如下圖所示:
核心代碼
創建一個內部類繼承Handler
1 /* 2 創建一個內部Handler類 3 */ 4 class NetworkHandler extends Handler{ 5 6 @Override 7 public void handleMessage(Message msg) { 8 Log.i("DemoHandler", "run: thread id2="+Thread.currentThread().getName()); 9 String s = (String) msg.obj; 10 txtInfo.setText(s); 11 } 12 }
創建一個內部類,繼承Thread
1 /* 2 創建一個線程內部類 3 */ 4 class NetworkThread extends Thread{ 5 @Override 6 public void run() { 7 Log.i("DemoHandler", "run: thread id1="+Thread.currentThread().getName()); 8 //模擬網路獲取,當執行時休眠2秒鐘 9 try { 10 Thread.sleep(2*1000); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 //通過handler將線程數據,發送到消息隊列中 15 //1. Looper將消息隊列中的消息對象取出。 16 //2. Looper找到消息對象對應的Handler對象 17 //3. Looper將會調用handler對象中的handleMessage(Msg)方法,處理對象 18 String s="這是一個線程中的數據"; 19 Message msg=handler.obtainMessage(); 20 msg.what=1; 21 msg.obj=s; 22 handler.sendMessage(msg); 23 } 24 }
啟動線程
1 public void click_me(View v){ 2 //點擊事件中啟動一個線程 3 Thread thread=new NetworkThread(); 4 thread.start(); 5 }
調試輸出信息(兩個分屬不同的線程)
1 04-25 22:56:37.424 18601-18786/com.hex.demohandler I/DemoHandler: run: thread id1=Thread-4 2 04-25 22:56:39.425 18601-18601/com.hex.demohandler I/DemoHandler: run: thread id2=main 3 04-25 22:56:55.491 18601-18800/com.hex.demohandler I/DemoHandler: run: thread id1=Thread-5 4 04-25 22:56:57.492 18601-18601/com.hex.demohandler I/DemoHandler: run: thread id2=main
備註
大多數情況下,在worker thread中修改view是不可以的,小部分是可以的,如progressbar 。