Android:如何将Progressbar添加到BitmapWorkerTask?

时间:2013-04-10 12:53:37

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

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

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;
    }
}

2 个答案:

答案 0 :(得分:0)

考虑如何加载你的Bitmap

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);
}

答案 1 :(得分:0)

嗯,只花了4个小时做了'不可能',诀窍是:

  1. 在将图像从HTTP URL加载到BitmapWorkerTask之前测量进度。这个link是一个很好的教程。
  2. 将进度更新从加载URL方法传递到BitmapWorkerTask类,但publishProgress()方法仅适用于AsyncTask,因此要解决this之后的问题。
  3. 还有大量的故障排除,试验和错误,可根据您的需求进行定制。
  4. 祝你好运!希望这有助于那些人开始朝着正确的方向前进。