android企業開發學習——handler

來源:互聯網
上載者:User

標籤:

我學習Handler是按照這樣的思路,所以我也按照這個的思路來寫:1.Handler是什嗎?2. Handler幹了些什嗎?3.我們應該怎樣利用Handler針對不同的情境來實現不同的功能                                                                                        (一) Handler是什嗎?                Handler,顧名思義就是“處理者”,用來發送和接受資訊並且按照資訊的匹配來實現執行功能代碼。它包含線程隊列和訊息佇列,實現非同步訊息處理機制在android裡面被運用很巧妙。        Androud啟動時,首先會開啟一個主線程 (也就是UI線程) , 主線程為管理介面中的UI控制項,進行事件分發,來響應客戶的操作。 如果此時需要一個耗時的操作,例如: 要連網去下載一個東西,我們是不能把這些操作放在主線程中,會很容易導致“ARN”異常。如果你放在主線程中的話,介面會出現假死現象, 如果5秒鐘還沒有完成的話,,會收到Android系統的一個錯誤提示 "強制關閉". 這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,Android主線程是線程不安全的,也就是說,更新UI只能在主線程中更新,子線程中操作是危險的. 這個時候,Handler就出現了.,來解決這個複雜的問題 , 由於Handler運行在主線程中(UI線程中), 它與子線程可以通過Message對象來傳遞資料, 這個時候,Handler就承擔著接受子線程傳過來的(子線程用sendMessage()方法傳弟)Message對象,(裡麵包含資料) , 把這些訊息放入主線程隊列中,配合主線程進行更新UI。                                                                                              (二) Handler幹了些什嗎?    handler可以分發Message對象和Runnable對象到主線程中, 每個Handler執行個體,都會綁定到建立它的線程中(一般是位於主線程),     它有兩個作用:         (1)安排訊息或Runnable 在某個主線程中某個地方執行;        (2)安排一個動作在不同的線程中執行       那麼,要實現上述的兩個功能,我們得基於發送和接受資訊的基礎,先瞭解下怎麼發送和處理。    它分發訊息的一些方法       post(Runnable)        postAtTime(Runnable,long)        postDelayed(Runnable long)        sendEmptyMessage(int)        sendMessage(Message)  將訊息發送到訊息佇列        msg.sendToTarget()  將訊息發送到訊息佇列        sendMessageAtTime(Message,long) 定時將訊息發送到訊息佇列        sendMessageDelayed(Message,long) 延遲一定時間後,將訊息發送到訊息佇列         以上post類方法允許你排列一個Runnable對象到主線程隊列中,        sendMessage類方法, 允許你安排一個帶資料的Message對象到隊列中,等待更新.(Message裡可以包含資料) 知識補充之Message怎麼包含資料:(1)Message對象       Message對象攜帶資料,通常它用arg1,arg2來傳遞訊息,當然它還可以有obj參數,可以攜帶Bundle資料。它的特點是系統效能消耗非常少。       初始化: Message msg=handler.obtainMessage();(2)Bundle對象      Bundle是Android提供的類,可以把它看做是特殊的Map,即索引值對的包。而它特殊在鍵和值都必須要是基礎資料型別 (Elementary Data Type)或是基礎資料型別 (Elementary Data Type)的數組(Map的索引值要求都是對象),特別的,鍵要求都是String類型。用Message來攜帶Bundle資料:           放入:msg.setData(Bundle bundle);           取出:msg.getData();     一般我都是藉助Bundle類。代碼                 Bundle bundle = new Bundle();                 bundle.putInt("myage", 21);                 bundle.putString("myname", "yummylau");                 msg.setData(bundler);                 msg.sendToTarget();  代碼               Bundle myData = msg.getData();              int myage = myData.getInt("myage");              String myname = myData.getString("myname");  希望對大家有協助。             它處理訊息的一般做法    訊息的具體處理過程,需要在new Handler對象時使用匿名內部類重寫Handler的handleMessage(Message msg)方法,如下:         Handler handler=new Handler(){          @Override          public void handleMessage(Message msg)                 //寫上自己想要執行的功能代碼           }         };                                                                     (三)我們應該怎樣利用Handler針對不同的情境來實現不同的功能         一般我們建立一個Handler對象,主要是想利用Handler來和UI線程互動,Handlre可以是UI線程的,也可以是新線程裡面的。   (1)通過handler的延時發送message,可以延時處理一些事務的處理    比如我想設計某一個應用的啟動時有一個歡迎介面,讓這個介面停留幾秒後再跳轉到裡一個Activity首頁             public class SplashActivity extends Activity{                      private Intent intent;                    @Override                   protected void onCreate(Bundle savedInstanceState) {                               // TODO Auto-generated method stub                      super.onCreate(savedInstanceState);                   setContentView(R.layout.splash);                    startMainAvtivity();                     }                private void startMainAvtivity(){                    new Handler().postDelayed(new Runnable(){                             @Override                             public void run() {                              intent = new Intent(SplashActivity.this,MainActivity.class);                           startActivity(intent);                            SplashActivity.this.finish();                       }                   }, 3000);                }               }      }         上述紅色代碼的利用Handler來延遲啟動另一個Activity。    值得注意的是:有一些小夥伴會認為,我們在主線程裡面啟動了新線程,然後在新線程裡面跳轉了Activity。其實一開始我也是這樣認為的,在學習的過程中看到了一位網上的朋友寫的博文和測試,也反思了一下,請教了一些師兄。只要記住:java裡面啟動新線程有兩種方法(個人知識所限),一種是利用一個類去繼承Thread,然後執行個體化後執行start()方法;另一種是實現Runable介面,把Runnable對象作為參數去執行個體化一個Thread對象再執行start()方法。    下面例子是參考網上朋友的:Java代碼  package org.hualang.handlertest3;    import android.app.Activity;  import android.os.Bundle;  import android.os.Handler;  import android.util.Log;    public class HandlerTest3 extends Activity {      private Handler handler = new Handler();      private String TAG = "System.out";      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          handler.post(r);          setContentView(R.layout.main);          //Thread t = new Thread(r);          //t.start();                    Log.d(TAG,"Activity id:"+Thread.currentThread().getId());          Log.d(TAG,"Activity name:"+Thread.currentThread().getName());                }      Runnable r = new Runnable()      {          public void run()          {              Log.d(TAG,"Handler id:"+Thread.currentThread().getId());              Log.d(TAG,"Handler name:"+Thread.currentThread().getName());              try {                  Thread.sleep(5000);              } catch (InterruptedException e) {                  // TODO Auto-generated catch block                  e.printStackTrace();              }          }      };  }  運行結果證明是同一個線程的兩個依據:①Activity的id或name和Handler的id或name是同樣的②設定了           handler.post(r);           setContentView(R.layout.main);也就是,如果執行後馬上顯示文本資訊,那麼可以證明它們不在同一個線程,但是實際情況是要先執行了handler後5秒,才顯示文本資訊,說明它們在同一線程如果將代碼改為            handler.post(r);             setContentView(R.layout.main);             Thread t = new Thread(r);              t.start();  再次執行,運行結果如下,通過start啟動線程,它們不在同一個線程中(2)利用handler發送message,然後不同線程接受和處理該訊息。顯然,我們在Android裡面利用Handler更多的是想在非同步線程裡面實現我們想要的東西    我把Handler處理非同步分解成兩個方面: △1在UI線程建立Handler,由非UI線程發送資訊UI線程接受資訊;(用於更新UI)代碼:運行結果:這個例子和上述的例子相似,不過在與Handler建立的線程不一樣。上述例子比較局限,因為我們在做項目的時候不可能都寫在同一檔案裡面,如果我們在不同檔案而要拿到同一個Handler對象,我們可以考慮利用“構造器”的方法,把Handler對象作為參數進行傳遞,就可以實現不同檔案的公用;或者我們可以定義成static。 android中其實還給了我們一個類HandlerThread,該類封裝好了Looper和MessageQueue(個人測試之後認為,如果不對請指出哦)。例子是按照上面的例子改寫的,非UI線程處理UI線程發送的訊息。直接上代碼:運行結果:從例子上看 ,效果是和上一個例子基本是一樣的,少了Looper.prepare()和Looper.loop();本人對這個類不太熟悉,請大神指點一二。     在使用Handler的時候只要時刻謹記Handler在哪一個線程建立post執行所在的線程;HandlerUI線程操作和非UI線程操作的區別和定時執行某些動作。就能基本掌握了。android非同步線程還可以使用AsyncTask執行非同步任務。其底層實現還是基於Handler。 原文地址:http://www.360doc.com/content/14/0108/13/7673502_343568991.shtml

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.