android 解決假死問題

來源:互聯網
上載者:User

轉自:http://406547509.blog.163.com/blog/static/456753862010112914328899/

 

是我們在開發Android程式時遇到較耗時任務的處理,如I/O訪問的資料庫操作、網路訪問等情況時造成UI假死等問題,通過 AsyncTask可以很好的解決這個問題,就今天以在Android中執行Downloader.downloadFile(url),可能會堵塞整個介面。顯然這會影響使用者體驗,我們如何解決這個問題呢?

  方法一、

  建立一個新的線程執行我們的任務,使用Thread類,在 run(){}中寫入任務代碼,比如:

  new Thread(new Runnable() {

  public void run() {

  Downloader.downloadFile(url);

  }

  }).start();

  但使用Thread會產生一些意想不到的問題,需要程式員用更多的代碼手動的維護它。

  方法二: Android SDK為我們提供了一個背景工作的處理工具AsyncTask。AsyncTask就是一個封裝過的背景工作類顧名思義就是非同步任務,方便我們維護,Android開發網提示這樣的好處可以解決一些安全執行緒問題,AsyncTask直接繼承於Object類,位置為 android.os.AsyncTask。要使用AsyncTask工作我們要提供三個泛型參數,並重載四個方法(至少重載一個)。

  三個泛型:

  Param ,任務執行器需要的資料類型

  Progress 後台計算中使用的進度單位元據類型

  Result 後台計算返回結果的資料類型

  有些參數是可以設定為不使用的,只要傳遞為Void型即可,比如AsyncTask

  四個步驟:

  onPreExecute(),執行預先處理,它運行於UI線程,可以為背景工作做一些準備工作,比如繪製一個進度條控制項。

  doInBackground(Params...),後台進程執行的具體計算在這裡實現,doInBackground(Params...)是AsyncTask的關鍵,此方法必須重載。在這個方法內可以使用 publishProgress(Progress...)改變當前的進度值。

  onProgressUpdate(Progress...),運行於UI線程。如果在doInBackground(Params...) 中使用了publishProgress(Progress...),就會觸發這個方法。在這裡可以對進度條控制項根據進度值做出具體的響應。

  onPostExecute(Result),運行於UI線程,可以對背景工作的結果做出處理,結果就是doInBackground(Params...)的傳回值。此方法也要經常重載,如果Result為null表明背景工作沒有完成(被取消或者出現異常)。

  Java代碼

  public class main extends Activity {

ImageView imageView01;

  TextView textView;

  @Override

  public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.main);

  textView = (TextView) this.findViewById(R.id.TextView01);

  imageView01 = (ImageView) this.findViewById(R.id.ImageView01);

  GetImage getImage = new GetImage();

  getImage.execute("http://hi.csdn.net/attachment/201010/27/0_1288149117Yk8W.gif");

  }

  private class GetImage extends AsyncTask {

  public GetImage() {

  super();

  // TODO Auto-generated constructor stub

  }

  @Override

  protected void onCancelled() {

  Log.i("czb", "onCancelled is running...");

  super.onCancelled();

  }

  @Override

  protected void onPostExecute(Object result) {

  /*

  * 此方法在主線程執行,任務執行的結果作為此方法的參數返回

  */

  Log.i("czb", "onPostExecute is running...");

  Log.i("czb", "result == null ? " + (result == null));

  imageView01.setImageBitmap((Bitmap)result);

  super.onPostExecute(result);

  }

  @Override

  protected void onPreExecute() {

  /*

  * 執行預先處理,它運行於UI線程,可以為背景工作做一些準備工作,比如繪製一個進度條控制項

  */

  Log.i("czb", "onPreExecute is running...");

  super.onPreExecute();

  }

  @Override

  protected void onProgressUpdate(Object... values) {

  /*

  * 此方法在主線程執行,用於顯示任務執行的進度。

  */

  Log.i("czb", "onProgressUpdate is running...");

  // 由publishProgress傳遞的值

  Log.i("czb", "values " + values[0]);

  super.onProgressUpdate(values);

  }

  @Override

  protected Object doInBackground(Object... params) {

/*

  * 此方法在後台線程執行,完成任務的主要工作,通常需要較長的時間。

  * 在執行過程中可以調用publicProgress(Progress…)來更新任務的進度。

  */

  Log.i("czb", "doInBackground is running...");

  try {

  Bitmap bitmap;

  HttpClient client = new DefaultHttpClient();

  // params[0]代表串連的url

  URI uri = URI.create((String) params[0]);

  HttpGet get = new HttpGet(uri);

  HttpResponse response = client.execute(get);

  HttpEntity entity = response.getEntity();

  long length = entity.getContentLength();

  Log.i("czb", " " + length);

  InputStream in = entity.getContent();

  if (in != null) {

  ByteArrayOutputStream baos = new ByteArrayOutputStream();

  /*byte[] buf = new byte[128];

  int ch = -1;

  int count = 0;

  while ((ch = in.read(buf)) != -1) {

  baos.write(buf, 0, ch);

  count += ch;

  if (length > 0) {

  // 如果知道響應的長度,調用publishProgress()更新進度

  // onProgressUpdate讀取進度

  publishProgress((int) ((count / (float) length) * 100));

  }

  // 為了在模擬器中清楚地看到進度,讓線程休眠100ms

  //Thread.sleep(100);

  }*/

  bitmap = BitmapFactory.decodeStream(in);

  in.close();

  baos.close();

  return bitmap;

  }

  } catch (Exception e) {

  e.printStackTrace();

  }

  return null;

  }

  }

  }

相關文章

聯繫我們

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