Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android之handler

android之handler

編輯:關於Android編程

android中handler的基本使用方法以及運行原理。

最近看mars的android重置版第二季的視頻關於handler的講解,讓我對於這個以前知道怎麼用,卻不是很明白原理的組件的理解瞬間加深了無數倍。mars真的講的很好,視頻真的都蠻不錯的。下面我寫寫自己學習到的知識,以及自己的了解。

handler的基本運行原理 handler怎樣從worker thread傳輸數據到main thread handler怎樣從main thread傳輸數據到worker thread handler的post()方法

handler的基本運行原理

為什麼我們需要一個handler?我想這是一個最重要的問題,也就是說handler的作用到底是什麼?handler主要是用於線程間的通信,那麼問題又來了,為什麼一個app中需要多個線程,而不是只有一個UI主線程就可以了呢?

假如app中只有一個UI主線程,那麼,當需要進行網絡連接,網絡下載這些等待耗時較長的任務時,android系統就會檢測到UI主線程長時間沒有響應,就會發出一個 application not response的異常警告,簡稱ANR問題。所以,在UI主線程中,是要與用戶實時交互的,不能出現長時間的等待問題。於是,這些任務必須在worker thread中進行。

然而根據android的設定,UI主線程之外的線程,(除了特別的控件,例如progressbar)不能修改UI裡的控件的,這樣又出現了新的問題,我們在子線程獲得的數據,該如何反應的UI上與用戶進行交互?這樣,就出現了這個巧妙的組件,handler!

那麼,handler到底是如何運行的呢?handler對象首先取出一個消息對象,存入到一個消息隊列messagequeue中,然後在另外一端,有一個looper對象,循環的從消息隊列中取出消息對象再交給handler去處理。

handler怎樣從worker thread傳輸數據到main thread

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);
//    點擊button啟動新線程
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                Thread thread = new Mythread();
                thread.start();

            }
        });
        handler = new Myhandler();
    }

//  復寫hanlder中的handlerMessage方法,處理從消息隊列中得到的消息
    class Myhandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String s = msg.obj.toString();
            System.out.println("在當前線程中"+Thread.currentThread().getName()+"獲得來自這個線程的消息"+s);
        }
    }

//  在worker thread中使用handler.obtainMessage()方法得到一個Message對象,再把消息存入message中,發入消息隊列
    class Mythread extends Thread{
        @Override
        public void run() {
            Message msg = handler.obtainMessage();
            msg.obj = currentThread().getName();
            handler.sendMessage(msg);
        }
    }
}

通過這個例子,我們可以看到,handlerMessage()方法是運行在主線程中的,而他可以得到來自worker thread的消息,這樣,就可以將消息在UI界面更新了。

為什麼只是初始化了一個handler對象,就會自動調用他的handleMessage方法?是因為在android.os.Handler類中有一個looper對象,會循環的從消息隊列中取出消息,調用handleM而是撒個方法。

handler怎樣從main thread傳輸數據到worker thread

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);

//      每點擊一次button,給worker thread 發送一個消息
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
//              在main中使用handler.obtainMessage()方法得到一個Message對象,再把消息存入message中,發入消息隊列
                Message msg = handler.obtainMessage();
                msg.obj = Thread.currentThread().getName();
                handler.sendMessage(msg);
            }
        });
        Thread thread = new Mythread();
        thread.start();


    }

//  復寫hanlder中的handlerMessage方法,處理得到的消息
    class Myhandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String s = msg.obj.toString();
            System.out.println("在當前線程中"+Thread.currentThread().getName()+"獲得來自這個線程的消息"+s);
        }
    }

//  work thread 接受這個消息,並調用handleMeesage()方法處理消息
    class Mythread extends Thread{
        @Override
        public void run() {
//      looper對象的loop方法從消息隊列中取出消息,調用handleMeesage()方法處理消息
            Looper.prepare();
            handler = new Myhandler();
            Looper.loop();
        }
    }
}


通過運行結果可以知道,handleMessage()方法運行在worker thread中,這樣就可以在worker thread中處理來自主線程的消息,實現了進程間的通信。

handler的post()方法

post方法通過生成一個message,然後把Runnable對象放在message中,再把message放在消息隊列中,然後在主線程中取出這個Runnable對象,在主線程中執行。

public class MainActivity extends ActionBarActivity {

    private Handler handler;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.cancleButton);
//      初始化handler,處理得到的Runnable對象
        handler = new Handler();

//      點擊按鈕執行worker thread
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                Thread thread = new Mythread();
                thread.start();
            }
        });

    }
    class Mythread extends Thread{
        @Override
        public void run() {
//          在worker thread 中初始化一個Runnable對象
            Runnable runnable = new Runnable() {
                public void run() {
//          打印出該Runnable方法執行的線程    
                    System.out.println("當前線程名"+Thread.currentThread().getName());
                }
            };
//          post該Runnable對象
            handler.post(runnable);
        }
    }
}

最後的結果,是這個Runnable對象執行在main線程中。有了post()方法,我們可以直接在worker thread中先生成一個Runnable對象,然後在其中寫上更新UI的代碼,直接用post方法即可更新UI。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved