淺談Android之於新線程創建Handler

Handler作爲Android中舉足輕重的知識點,無論是在實際開發還是在面試中都經常會用到,並且在網上關於Handler的講解不勝枚舉,本人深知水平有限,因此僅在此做一下自己的小結,權當學習中的筆記。

之前寫過一篇有關Handler中基本方法使用的一篇文章http://blog.csdn.net/james_shu/article/details/53367035,本篇基於此,寫出一些其他的新內容。

Android中的異步消息處理主要由4個部分組成:Message、Handler、MessageQueue和Looper。其中,
Message:Message是在線程之間傳遞的消息,當我們在不同的線程中傳遞數據時,Handler將我們要傳遞的信息封裝到Message中然後進行傳遞。
Handler:Handler主要是用於發送消息,接受並處理消息。
MessageQueue:消息隊列,它主要用於存放Handler發送的消息。存放於消息隊列中的消息等待被處理,每一個線程中只會有一個MessageQueue對象。
Looper:Looper是每一個線程中的MessageQueue的管家,調用Looper的loop()方法之後就會進入到一個無限循環中,然後當發現MessageQueue中存在一條消息就會將其取出並將這條消息傳遞到Handler的handleMessage()方法,每一個線程中只會有一個Looper對象。

這裏應該提到的一點是:
主線程中默認初始化了Looper,因此我們可以在創建Handler之後直接發送消息和處理消息,其中處理消息一定是創建Handler所在的線程中處理消息,而發送消息就可以在不同的線程中發送消息。
當我們創建一個新的線程的時候(不在主線程時),此時我們如果需要在新線程中創建Handler作爲其他線程與所創建的當前線程的通信的橋樑時,我們需要首先創建Looper對象,然後創建Handler對象。

下面我們以計算指定區間的質數爲例來介紹在新線程中創建Handler的用法:
佈局文件:

  <EditText
        android:id="@+id/etNum"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:onClick="calculate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="點擊得到處理的結果"
        />

代碼:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        calThread=new CalThread();
        calThread.start();
    }

    private void initView() {
        etNum= (EditText) findViewById(R.id.etNum);//使用Handler將用戶在UI界面輸入的數值上限動態的傳遞給新啓動的線程

    }


    class CalThread extends Thread{
        public Handler mHandler;                //在新線程中創建Handler,作爲主線程與新線程的通信的橋樑
        //在主線程中系統已經初始化了一個Looper對象,因此程序可以直接創建handler對象然後使用創建的Handler對象來發送消息和處理消息
        //然而當自己創建一個新的線程的時候,爲了使用自己創建的Handler對象,此時就應該自己同時創建一個Looper對象,此時Handler的功能纔算是完整的
        @Override
        public void run() {
            super.run();
            Looper.prepare();
            mHandler=new Handler(){
                //定義處理消息的方法
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    if(msg.what==0x123){
                        int upper=msg.getData().getInt(UPPER_NUM);
                        List<Integer> nums=new ArrayList<Integer>();
                        //計算從二開始的質數
                        outer:
                        for (int i=2;i<=upper;i++){
                            for (int j=2;j<=Math.sqrt(i);j++){
                                if(i!=2&&i%j==0){
                                    continue outer;
                                }
                            }
                            nums.add(i);
                        }
                        Toast.makeText(MainActivity.this,nums.toString(),Toast.LENGTH_SHORT).show();
                    }
                }
            };
            Looper.loop();
        }
    }

    public void calculate(View view){
        Message msg=new Message();
        msg.what=0x123;
        Bundle bundle=new Bundle();
        bundle.putInt(UPPER_NUM,Integer.parseInt(etNum.getText().toString()));
        msg.setData(bundle);
        calThread.mHandler.sendMessage(msg);
    }
發佈了123 篇原創文章 · 獲贊 47 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章