2011年12月21日 星期三

Android 更新UI

只要有寫過Android程式的人,幾乎都會碰過要在thread中更新UI,以下就解說一下各種更新方法:
1.Handler
寫過Java的人最初應該就會想到這種方法,簡單且容易理解。
mHandler = new Handler() {
   @Override
   public void handleMessage(Message msg) {
        //更新界面
       myText.setText( "update");
      super.handleMessage(msg);
   }
  };
public class MyThread extends Thread {
     public void run() {
​    ​    ​    doSomething();
            Message msg = new Message();
            mHandler.sendMessage(msg);//向Handler發送消息,
      }
 }
2.Activity.runOnUiThread(Runnable ) or View.post(Runnable )
runOnUiThread是Android工程師設計出來的偷懶方法,內部實作其實也是靠handler做處裡,如果只是要更新一點點的UI,用這方法應該最快也最省事。View.post跟runOnUiThread很相近,只是變成用元件自己呼叫post更新自己,如果同時更新多項元件使用起來會蠻奇怪的,所以我比較偏向使用runOnUiThread。
public void onClick( View v ) {
        new Thread( new Runnable() {
                public void run() {
                         doSomething();
​                         runOnUiThread.( new Runnable() {
                                  myText.setText(  "update" );
                          });
                 }
        }).start();
}
public void onClick( View v ) {
        new Thread( new Runnable() {
                public void run() {
​    ​    ​    ​    ​    ​      doSomething();
​                          myText.post( new Runnable() {
                                  myText.setText( "update" );
                          });
                 }
        }).start();
}
3.AsyncTask
遇到需要載入圖形更新UI的時候,往往就會選擇使用AsyncTask,他可以在背景載入圖片,並在完成後更新下載好的圖形。不過要注意的是,如果要載入多個圖形但有重複圖形時,則要在doInBackground()中使用synchronized()等同步機制確保不會一再重複載入同一張圖形,因為當執行execute()後,每個doInBackground()都會並行執行,而非循序執行,若無設定同步機制,則相同的圖片可能會一再載入,拖慢整體速度。
 private class LoadImage extends AsyncTask {
     protected String doInBackground( String... url ) {
          return loadImageFormNetwork( url[0] );
     }

     protected void onPostExecute( String result ) {
           myImage.setImage( result ); 
    }
 //需要背景下載或載入圖形並更新UI
 new loadImageTask().execute( "www.xxx.com/image.png" );

沒有留言:

張貼留言