【问题标题】:ProgressBar in AsyncTask crashesAsyncTask 中的 ProgressBar 崩溃
【发布时间】:2015-02-03 07:48:42
【问题描述】:

AsyncTask 中的ProgressBar 导致崩溃。此代码实质上是从 URL 加载图像,同时显示进度微调器。该组中的第一张图片加载正常,但随后应用程序崩溃。

public class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
ProgressBar progressBar;

public LoadImageTask(ImageView bmImage, ProgressBar progressBar) {
    this.bmImage = bmImage;
    this.progressBar = progressBar;
}

protected Bitmap doInBackground(String... urls) {
    progressBar.setVisibility(View.VISIBLE);
    String urldisplay = urls[0];
    Bitmap scaledImage = null;
    try {
        InputStream in = new java.net.URL(urldisplay).openStream();
        Bitmap image = BitmapFactory.decodeStream(in);

        scaledImage = Bitmap.createScaledBitmap(image, 380, 250, false);
    } catch (Exception e) {
        Log.e("Error", e.getMessage());
        e.printStackTrace();
    }
    return scaledImage;
}

protected void onPostExecute(Bitmap result) {
    progressBar.setVisibility(View.GONE);
    bmImage.setImageBitmap(result);
}

}

控制台打印输出:

 02-03 02:45:44.014  24125-24375/simplewall.ryandushane.com.simplewall E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #5
    Process: simplewall.ryandushane.com.simplewall, PID: 24125
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.AbsListView.requestLayout(AbsListView.java:1975)
            at android.view.View.requestLayout(View.java:17364)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
            at android.view.View.requestLayout(View.java:17364)
            at android.view.View.setFlags(View.java:9633)
            at android.view.View.setVisibility(View.java:6663)
            at android.widget.ProgressBar.setVisibility(ProgressBar.java:1563)
            at simplewall.ryandushane.com.simplewall.LoadImageTask.doInBackground(LoadImageTask.java:27)
            at simplewall.ryandushane.com.simplewall.LoadImageTask.doInBackground(LoadImageTask.java:17)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)

【问题讨论】:

    标签: java android android-asynctask android-progressbar


    【解决方案1】:

    CalledFromWrongThreadException:只有创建的原始线程 视图层次结构可以触及它的视图

    因为您正在从doInBackground 调用progressBar.setVisibility 方法,该方法在非ui 线程上运行。

    覆盖在主 UI 线程上运行的 AsyncTaskonPreExecute() 方法以更改进度条的可见性:

    @Override
    protected void onPreExecute() {
         progressBar.setVisibility(View.VISIBLE);
    }
    

    【讨论】:

      【解决方案2】:

      您不能在doInBackground 中设置progressBar.setVisibility(View.VISIBLE);。这是一个不同的线程

      protected Bitmap doInBackground(String... urls) {
          runOnUiThread (new Runnable () {
      
                              @Override
                              public void run () {
      
                                  progressBar.setVisibility(View.VISIBLE);
      
                              }
                          });
      
          String urldisplay = urls[0];
          Bitmap scaledImage = null;
          try {
              InputStream in = new java.net.URL(urldisplay).openStream();
              Bitmap image = BitmapFactory.decodeStream(in);
      
              scaledImage = Bitmap.createScaledBitmap(image, 380, 250, false);
          } catch (Exception e) {
              Log.e("Error", e.getMessage());
              e.printStackTrace();
          }
          return scaledImage;
      }
      

      【讨论】:

        【解决方案3】:

        progressBar.setVisibility(View.VISIBLE); 移入onPreExecute

        【讨论】:

          【解决方案4】:

          将此progressBar.setVisibility(View.VISIBLE) 放入AsyncTask 的onPreExecute() 方法中,并从doInBackground 方法中删除此行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-08
            • 1970-01-01
            • 1970-01-01
            • 2021-06-28
            • 2013-05-13
            相关资源
            最近更新 更多