Android--多線程之Handler

來源:互聯網
上載者:User

標籤:url   blank   等等   介紹   延遲   listen   class   ui組件   rem   

 

前言

  Android的訊息傳遞機制是另外一種形式的“事件處理”,這種機制主要是為瞭解決Android應用中多線程的問題,在Android中不允許Activity新啟動的線程訪問該Activity裡的UI組件,這樣會導致新啟動的線程無法改變UI組件的屬性值。但實際開發中,很多地方需要在背景工作執行緒中改變UI組件的屬性值,比如下載網狀圖片、動畫等等。本篇部落客要介紹Handler是如何發送與處理線程上傳遞來的訊息,並講解Message的幾種傳遞資料的方式,最後均會以小Demo來示範。

 

Handler

  Handler,它直接繼承自Object,一個Handler允許發送和處理Message或者Runnable對象,並且會關聯到主線程的MessageQueue中。每個Handler具有一個單獨的線程,並且關聯到一個訊息佇列的線程,就是說一個Handler有一個固有的訊息佇列。當執行個體化一個Handler的時候,它就承載在一個線程和訊息佇列的線程,這個Handler可以把Message或Runnable壓入到訊息佇列,並且從訊息佇列中取出Message或Runnable,進而操作它們。

  Handler主要有兩個作用:

  • 在背景工作執行緒中發送訊息。
  • 在UI線程中擷取、處理訊息。

  上面介紹到Handler可以把一個Message對象或者Runnable對象壓入到訊息佇列中,進而在UI線程中擷取Message或者執行Runnable對象,所以Handler把壓入訊息佇列有兩大體系,Post和sendMessage:

  • Post:Post允許把一個Runnable對象入隊到訊息佇列中。它的方法有:post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)。
  • sendMessage:sendMessage允許把一個包含訊息資料的Message對象壓入到訊息佇列中。它的方法有:sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)。

  從上面的各種方法可以看出,不管是post還是sendMessage都具有多種方法,它們可以設定Runnable對象和Message對象被入隊到訊息佇列中,是立即執行還是順延強制。

  

Post

  對於Handler的Post方式來說,它會傳遞一個Runnable對象到訊息佇列中,在這個Runnable對象中,重寫run()方法。一般在這個run()方法中寫入需要在UI線程上的操作。

  在Handler中,關於Post方式的方法有:

  • boolean post(Runnable r):把一個Runnable入隊到訊息佇列中,UI線程從訊息佇列中取出這個對象後,立即執行。
  • boolean postAtTime(Runnable r,long uptimeMillis):把一個Runnable入隊到訊息佇列中,UI線程從訊息佇列中取出這個對象後,在特定的時間執行。
  • boolean postDelayed(Runnable r,long delayMillis):把一個Runnable入隊到訊息佇列中,UI線程從訊息佇列中取出這個對象後,延遲delayMills秒執行
  • void removeCallbacks(Runnable r):從訊息佇列中移除一個Runnable對象。

   下面通過一個Demo,講解如何通過Handler的post方式在新啟動的線程中修改UI組件的屬性:

 1 package com.bgxt.datatimepickerdemo; 2  3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; 9 10 public class HandlerPostActivity1 extends Activity {11     private Button btnMes1,btnMes2;12     private TextView tvMessage;13     // 聲明一個Handler對象14     private static Handler handler=new Handler();15     16     @Override17     protected void onCreate(Bundle savedInstanceState) {18         super.onCreate(savedInstanceState);19         setContentView(R.layout.message_activity);        20         21         btnMes1=(Button)findViewById(R.id.btnMes1);22         btnMes2=(Button)findViewById(R.id.btnMes2);23         tvMessage=(TextView)findViewById(R.id.tvMessage);24         btnMes1.setOnClickListener(new View.OnClickListener() {25             26             @Override27             public void onClick(View v) {28                 // 新啟動一個子線程29                 new Thread(new Runnable() {                    30                     @Override31                     public void run() {32                         // tvMessage.setText("...");33                         // 以上操作會報錯,無法再子線程中訪問UI組件,UI組件的屬性必須在UI線程中訪問34                         // 使用post方式修改UI組件tvMessage的Text屬性35                         handler.post(new Runnable() {                    36                             @Override37                             public void run() {38                                 tvMessage.setText("使用Handler.post在背景工作執行緒中發送一段執行到訊息佇列中,在主線程中執行。");                        39                             }40                         });                                41                     }42                 }).start();43             }44         });45         46         btnMes2.setOnClickListener(new View.OnClickListener() {47             48             @Override49             public void onClick(View v) {50                 new Thread(new Runnable() {                    51                     @Override52                     public void run() {53                         // 使用postDelayed方式修改UI組件tvMessage的Text屬性值54                         // 並且延遲3S執行55                         handler.postDelayed(new Runnable() {56                             57                             @Override58                             public void run() {59                                 tvMessage.setText("使用Handler.postDelayed在背景工作執行緒中發送一段執行到訊息佇列中,在主線程中延遲3S執行。");    60                                 61                             }62                         }, 3000);                        63                     }64                 }).start();65                 66             }67         });68     }69 }

Android--多線程之Handler

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.