Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android多線程更新UI的方式

Android多線程更新UI的方式

編輯:關於Android編程

Android下,對於耗時的操作要放到子線程中,要不然會殘生ANR,本次我們就來學習一下Android多線程更新UI的方式。     首先我們來認識一下anr:     anr:application not reponse:應用程序無響應   主線程:UI線程   anr產生的原因:主線程需要做很多重要的事情,響應點擊事件,更新ui,如果在主線程裡面阻塞時間過久,應用程序就會無響應,為了避免應用程序出現anr,所有的耗時的操作,都應該放在子線程中執行。     認識了anr後,我們就來學習一下怎樣在Android下開啟多線程,並更新ui了。一共有兩種方式:   第一種采用:Handler。     Handler獲取當前線程中的looper對象,looper用來從存有Message的Message Queue裡取出message,再由Handler進行message的分發和處理。   handler進制的原理:     android提供了handler和looper來滿足線程間的通信。Handler先進先出原則。looper用來管理特定線程內對象之間的消息交換(message Exchange).        1)looper:一個線程可以產生一個looper對象,由它來管理此線程裡的message queue(消息隊列)         2)handler:你可以構造一個handler對象來與looper溝通,以便push新消息到messagequeue裡;或者接收looper(從messagequeue裡取出)所送來的消息。   我們使用的時候呢,需要在子線程中定義message,並把要返回的obj對象,傳遞給msg,同時由於handler不止要處理這一種類型,所以我們還要定義what的類型,以便讓handler分類處理。     Message msg = new Message(); msg.what = CHANGE_UI; msg.obj = result; handler.sendMessage(msg);     好的接下來我們就實例來使用handler。   new Thread(){     public void run() {         try {          URL url = new URL(path);          HttpURLConnection conn = (HttpURLConnection) url.openConnection();          conn.setRequestMethod("GET");          conn.setConnectTimeout(5000);          conn.setRequestProperty("User-Agent", "");                     int code = conn.getResponseCode();          if(code==200){              InputStream is = conn.getInputStream();              String result = StreamTools.readInputStream(is);                             //tv_content.setText(result);              Message msg = new Message();              msg.what = CHANGE_UI;              msg.obj = result;              handler.sendMessage(msg);                                        }else{              Message msg = new Message();              msg.what = ERROR;              handler.sendMessage(msg);          }                 } catch (Exception e) {          // TODO Auto-generated catch block          e.printStackTrace();                     Message msg = new Message();          msg.what = ERROR;          handler.sendMessage(msg);                            }                         }; }.start();  這裡采用的 StreamTools.readInputStream的實現是這樣的,目的是把輸入流轉化為字符串。     /**      * 把輸入流轉化為字符串      * @param is      * @return      */     public static String readInputStream(InputStream is){         try {             ByteArrayOutputStream baos = new ByteArrayOutputStream();             int len = 0;             byte[] buffer = new byte[1024];             while((len = is.read(buffer))!=-1){                 baos.write(buffer,0,len);             }             is.close();             baos.close();             byte[] result = baos.toByteArray();                           //試著解析網址返回的字符串,             String temp = new String(result);             if(temp.contains("utf-8")){                 return temp;             }else if(temp.contains("gbk")){                 return new String(result,"gbk");             }                           return temp;             //return new String(result);         } catch (Exception e) {             // TODO Auto-generated catch block             e.printStackTrace();             return "獲取失敗";         }               }     其中handler的實現是這樣的。     private Handler handler = new Handler(){     public void handleMessage(android.os.Message msg) {         switch (msg.what) {         case ERROR:             Toast.makeText(MainActivity.this, "獲取數據失敗", 0).show();             break;         case CHANGE_UI:             tv_content.setText(msg.obj+"");             Toast.makeText(MainActivity.this, "獲取數據失敗", 0).show();             break;           }     }; };  這樣呢,我們便可以用handler,也即消息處理機制來更新UI了,       第二種方式。     采用runOnUiThread(new Runnable()),這要實現Runnable借口,我們可以直接在這個線程中進行UI的更新。是api提供的方法,較為便捷。        new Thread(){         @Override         public void run() {             final String result = LoginServices.loginByGet(username, password);             if(result != null){                 //成功                 runOnUiThread(new Runnable() {                                           @Override                     public void run() {                         // TODO Auto-generated method stub                         Toast.makeText(MainActivity.this, result, 0).show();                     }                 });             }else{                 //請求失敗                 runOnUiThread(new Runnable() {                                           @Override                     public void run() {                         // TODO Auto-generated method stub                         Toast.makeText(MainActivity.this, "請求失敗", 0).show();                     }                 });             }                       };     }.start();
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved