android UI安全執行緒問題

來源:互聯網
上載者:User

標籤:android   style   blog   http   color   os   使用   ar   for   

  在Android的子線程去更新UI的內容,會導致不確定的異常。

因為Android有個模式是,單一執行緒模式:Android UI工具箱(toolkit)不是一個安全執行緒的,並且它總是被放在主線程上操作。

public void onClick(View v) {  new Thread(new Runnable() {    public void run() {      Bitmap b = loadImageFromNetwork();      mImageView.setImageBitmap(b);    }  }).start();}

首先,從上面代碼看上去好像非常完美,因為它不會阻塞UI線程,不幸的是,它違背了單一執行緒模式:Android UI工具箱(toolkit)不是一個安全執行緒的,並且它總是被放在主線程上操作。

這個ImageView被一個背景工作執行緒操作,這導致非常不可思議的問題。跟蹤和修複這樣一個bug很難並且也耗時。Android提供了幾種從其他線程訪問主線程的方式:
  1. Activity.runOnUiThread(Runnable)
  2. View.post(Runnable)
  3. View.postDelayed(Runnable, long)
  4. Handler

以上任何一種方式都能修正我們的代碼:

public void onClick(View v) {  new Thread(new Runnable() {    public void run() {      final Bitmap b = loadImageFromNetwork();      mImageView.post(new Runnable() {        public void run() {          mImageView.setImageBitmap(b);        }      });    }  }).start();}

當然我們還有更簡單的方法,使用AsyncTask

不幸的是,這些類和方法導致我們的代碼變得複雜和可讀性差。當你實現複雜的操作來頻繁的更新介面,使用這種方式變得更加糟糕。為瞭解決這個問題,Android1.5提供了一個公用類叫做AsyncTask,它簡化了任務線程和主線程之間的通訊。         在Android1.0和1.1也可使用AsyncTask只不過它的名字為UserTask。        AsyncTask的目的就是協助你管理線程。我們之前的例子很容易被改寫如下形式:
public void onClick(View v) {  new DownloadImageTask().execute("http://example.com/image.png");}private class DownloadImageTask extends AsyncTask<string, integer, Bitmap> {     protected Bitmap doInBackground(String... urls) {         return loadImageFromNetwork(urls[0]);     }     protected void onPostExecute(Bitmap result) {         mImageView.setImageBitmap(result);     } }
AsyncTask通過它的子類才能使用。要記住,一個AsyncTask執行個體必須在主線程建立並且只能被執行一次。完全理解和使用這個類,你可以閱讀AsyncTask文檔。這裡快速的說一下AsyncTask是怎麼工作的:1>可以通過泛型指定它的類型:參數,進度值,任務的結果值。2>doInBackGround()方法自動在背景工作執行緒中只想能夠。3>onPreExecute(),onPostExecute(),onProgressUpdate()方法都在UI線程中執行。4>doInBackground()方法返回的值被當作參數傳遞給onPostExecute()方法。5>你能夠在doInBackground()方法裡任何時候調用publishProgress()方法在UI線程中去執行onProgressUpdate()方法。 下面寫一個重載方法比較多得類:
 1 package vic.wong.main; 2 import android.os.AsyncTask; 3 import android.widget.ProgressBar; 4 import android.widget.TextView; 5  6 /** 7  * 產生該類的對象,並調用execute方法之後 8  * 首先執行的是onProExecute方法 9  * 其次執行doInBackgroup方法10  *11  */12 public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {13     private TextView textView;14     private ProgressBar progressBar;15     public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {16         super();17         this.textView = textView;18         this.progressBar = progressBar;19     }20     /**21      * 這裡的Integer參數對應AsyncTask中的第一個參數 22      * 這裡的String傳回值對應AsyncTask的第三個參數23      * 該方法並不運行在UI線程當中,主要用於非同步作業,所有在該方法中不能對UI當中的空間進行設定和修改24      * 但是可以調用publishProgress方法觸發onProgressUpdate對UI進行操作25      */26     @Override27     protected String doInBackground(Integer... params) {28         NetOperator netOperator = new NetOperator();29         int i = 0;30         for (i = 10; i <= 100; i+=10) {31             netOperator.operator();32             publishProgress(i);33         }34         return i + params[0].intValue() + "";35     }36 37     /**38      * 這裡的String參數對應AsyncTask中的第三個參數(也就是接收doInBackground的傳回值)39      * 在doInBackground方法執行結束之後在運行,並且運行在UI線程當中 可以對UI空間進行設定40      */41     @Override42     protected void onPostExecute(String result) {43         textView.setText("非同步作業執行結束" + result);44     }45     //該方法運行在UI線程當中,並且運行在UI線程當中 可以對UI空間進行設定46     @Override47     protected void onPreExecute() {48         textView.setText("開始執行非同步線程");49     }50     /**51      * 這裡的Intege參數對應AsyncTask中的第二個參數52      * 在doInBackground方法當中,,每次調用publishProgress方法都會觸發onProgressUpdate執行53      * onProgressUpdate是在UI線程中執行,所有可以對UI空間進行操作54      */55     @Override56     protected void onProgressUpdate(Integer... values) {57         int vlaue = values[0];58         progressBar.setProgress(vlaue);59     }60 }

 

android UI安全執行緒問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.