我有一个活动,我从给定的URI加载图像。 Android培训文章建议它应该在后台完成,这样它就不会阻止UI。我遵循了相同的Article.
以下是我调用AsyncTask
的代码段 Uri uri = ....
ImageLoaderTask task = new ImageLoaderTask(imageView);
task.execute(uri);
我的ImageLoaderTask如下所示。
public class ImageLoaderTask extends AsyncTask<Uri, Void, Bitmap> {
private WeakReference<ImageView> imageViewReference;
public ImageLoaderTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
protected Bitmap doInBackground(Uri... params) {
Bitmap bitmap = ImageUtils
.decodeSampledBitmapFromFile(params[0], 200,
200);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
这几乎与上面指定的文章中描述的一样。
ImageUtils类中的代码如下所示
public static Bitmap decodeSampledBitmapFromFile(Uri uri,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
File imageFile = getImageFile(uri);
BitmapFactory.decodeFile(imageFile.getPath(), options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imageFile.getPath(), options);
}
private static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
当我调用task.execute(uri)时,应用程序崩溃了。我在手机中试了一下,而不是在模拟器上试了一下。我无法让我的模拟器在我的机器上运行,因为它需要太多时间。
可能的原因是什么?
答案 0 :(得分:1)
不要将ImaageView
引用传递给Async
类标准实践,而是尝试为加载位图定义自定义接口
public interface ImageBitampLoadListener {
public void onBitampLoad(Bitmap bitmap);
}
传递自定义界面参考Async
:
private ImageBitmapLoadListener listener;
public ImageLoaderTask(ImageBitmapLoadListener listener) {
this.listener = listener;
}
从Async
设置回叫:
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(listener!=null){
listener.onBitampLoad(bitmap);
}
}
将自定义监听器设置为Async
并获取Bitamp
:
ImageLoaderTask task = new ImageLoaderTask(new ImageBitmapLoadListener() {
@Override
public void onBitampLoad(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
});
task.execute(uri);
答案 1 :(得分:0)
我通过覆盖AsyncTask的onProgressUpdate()方法解决了这个问题。现在我的ImageLoader代码看起来像
=SUM(
COUNTIF(B5:B32,"*")*5,
COUNTIF(C5:C32,"*")*5,
COUNTIF(D5:D32,"*")*10,
COUNTIF(F5:F32,"*")*20)