【问题标题】:Android: how to add Progressbar to BitmapWorkerTask?Android:如何将进度条添加到 BitmapWorkerTask?
【发布时间】:2013-04-10 12:53:37
【问题描述】:

这是我将图像加载到 ViewPager 的 BitmapWorkerTask。我正在尝试向每个页面添加一个 Horizo​​ntal ProgressBar,以便更好地显示图像加载进度的 UX。 (我已经在使用“不确定”的圆形进度条了。)

BitmapWorkerTask 是否是添加进度条的正确位置,如果是,该怎么做?

/**
 * The actual AsyncTask that will asynchronously process the image.
 */
private class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> {
    private Object data;
    private final WeakReference<ImageView> imageViewReference;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    /**
     * Background processing.
     */
    @Override
    protected Bitmap doInBackground(Object... params) {            

        data = params[0];
        final String dataString = String.valueOf(data);
        Bitmap bitmap = null;

        // Wait here if work is paused and the task is not cancelled
        synchronized (mPauseWorkLock) {
            while (mPauseWork && !isCancelled()) {
                try {
                    mPauseWorkLock.wait();
                } catch (InterruptedException e) {}
            }
        }

        // If the image cache is available and this task has not been cancelled by another
        // thread and the ImageView that was originally bound to this task is still bound back
        // to this task and our "exit early" flag is not set then try and fetch the bitmap from
        // the cache
        if (mImageCache != null && !isCancelled() && getAttachedImageView() != null
                && !mExitTasksEarly) {
            bitmap = mImageCache.getBitmapFromDiskCache(dataString);
        }

        // If the bitmap was not found in the cache and this task has not been cancelled by
        // another thread and the ImageView that was originally bound to this task is still
        // bound back to this task and our "exit early" flag is not set, then call the main
        // process method (as implemented by a subclass)
        if (bitmap == null && !isCancelled() && getAttachedImageView() != null
                && !mExitTasksEarly) {
            bitmap = processBitmap(params[0]);
        }

        // If the bitmap was processed and the image cache is available, then add the processed
        // bitmap to the cache for future use. Note we don't check if the task was cancelled
        // here, if it was, and the thread is still running, we may as well add the processed
        // bitmap to our cache as it might be used again in the future
        if (bitmap != null && mImageCache != null) {
            mImageCache.addBitmapToCache(dataString, bitmap);
        }            

        return bitmap;
    }

    /**
     * Once the image is processed, associates it to the imageView
     */
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        // if cancel was called on this task or the "exit early" flag is set then we're done
        if (isCancelled() || mExitTasksEarly) {
            bitmap = null;
        }

        final ImageView imageView = getAttachedImageView();
        if (bitmap != null && imageView != null) {
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "onPostExecute - setting bitmap");
            }
            setImageBitmap(imageView, bitmap);
        }
    }

    @Override
    protected void onCancelled(Bitmap bitmap) {
        super.onCancelled(bitmap);
        synchronized (mPauseWorkLock) {
            mPauseWorkLock.notifyAll();
        }
    }

    /**
     * Returns the ImageView associated with this task as long as the ImageView's task still
     * points to this task as well. Returns null otherwise.
     */
    private ImageView getAttachedImageView() {
        final ImageView imageView = imageViewReference.get();
        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

        if (this == bitmapWorkerTask) {
            return imageView;
        }

        return null;
    }
}

【问题讨论】:

    标签: android progress-bar android-viewpager android-progressbar image-loading


    【解决方案1】:

    考虑您如何加载位图

    return BitmapFactory.decodeStream(params[0].openConnection().getInputStream());
    

    不可能给出实际的百分比进度。对于未定义的 progressBar,您可以将进度条传递给构造函数并将其保存在另一个 WeakReference 中,然后在您的代码中执行以下操作:

    // Before start hide the ImageView and show the progressBar
    @Override
    protected void onPreExecute(){
        // do the weak reference stuff and call
        progressBar.setVisibility(View.VISIBLE);
        imageView.setVisibility(View.INVISIBLE);
    }
    
    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
         // do the weak refence stuff and call
        progressBar.setVisibility(View.INVISIBLE);
        imageView.setVisibility(View.VISIBLE);
    }
    

    【讨论】:

    • 我的错误是我复制了错误的代码,现在它已经被编辑了应该是正确的。很抱歉给您带来不便,感谢您的帮助。
    • 我的答案不会因新代码而改变,我很高兴您使用缓存。
    • 哦,顺便说一句,我一直在使用“不确定”的圆形进度条。
    • 所以你已经准备好了 99%。只需从 preExecute 和 postExecute =] 调用图像和进度条的可见性
    • 抱歉没关系,我意识到这个不清楚的问题,已编辑。关键是我正在尝试使用水平进度条,因为我已经实现了圆圈。
    【解决方案2】:

    好吧,只花了 4 个小时,做了“不可能”,诀窍是:

    1. 测量从 HTTP URL 加载图像时的进度,然后再将其传递给 BitmapWorkerTask。这个link 是一个很好的教程。
    2. 将进度更新从加载 URL 方法传递给 BitmapWorkerTask 类,但是 publishProgress() 方法仅在 AsyncTask 中有效,因此可以解决 this 之后的问题。
    3. 还有大量的故障排除、反复试验,可根据您的需求进行专门定制。

    祝你好运!希望这可以帮助人们朝着正确的方向开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      相关资源
      最近更新 更多