为了更正此类错误,Android提供了多种方法使得在非UI线程中访问UI组件,下面给出了其中的几种方法:

  · Activity.runOnUiThread (Runnable) 方法

  · View.post (Runnable) 方法

  · View.postDelayed (Runnable) 方法

  比如,使用View.post(Runnable)修改上面的代码:

  [java] view plaincopyprint?

  public void onClick(View v) {

  new Thread(new Runnable() {

  public void run() {

  final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");

  mImageView.post(new Runnable() {

  public void run() {

  mImageView.setImageBitmap(bitmap);

  }

  });

  }

  }).start();

  }

  public void onClick(View v) {

  new Thread(new Runnable() {

  public void run() {

  final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");

  mImageView.post(new Runnable() {

  public void run() {

  mImageView.setImageBitmap(bitmap);

  }

  });

  }

  }).start();

  }

  这样的实现是符合“线程安全”原则的:在额外的线程中完成网络操作并且在UI线程中完成对ImageView的操作。

  然而,随着操作复杂性的增加,上述代码可能会变得非常复杂导致维护困难。为了解决工作线程中处理此类复杂操作,你可能会考虑在工作线程中使用Handler类来处理由UI线程发送过来的消息。但可能使用AsyncTask是此类问题的好解决方案,它很好的简化了工作线程需要和UI组件发生交互的问题。

  使用AsyncTask

  AsyncTask允许你完成一些和用户界面相关的异步工作。它在一个工作线程中完成一些阻塞工作任务然后在任务完成后通知UI线程,这些都不需要你自己来管理工作线程。

  你必须从AsyncTask派生一个子类并实现doInBackground()回调函数来使用AsyncTask,AsyncTask将使用后台进程池来执行异步任务。为了能够更新用户界面,你必须实现onPostExecute()方法,该方法将传递doInBackground()的返回结果,并且运行在UI线程中。然后你可以在UI线程中调用execute() 方法来执行该任务。