我是Android开发的新手,我对使用AsyncTask解码和缩放位图感到困惑。我已经阅读了android开发网站,这对我的理解没有帮助。我的问题是这是怎么做到的?我的目标是解码和缩放多个图像并将它们放在ImageViews中。 我是否在doInBackground方法中编码解码和缩放?任何帮助都将非常感谢!
答案 0 :(得分:0)
是的,您应该在doInBackground
上做任何事情。只有在您的图片准备就绪时才使用“返回”来调用onPostExecute
,而在onPostExecute
中,您应该将位图设置为imageView。
答案 1 :(得分:0)
在doInBackground方法中执行所有重载内容,然后在onPostExecute方法中设置图像。
启用严格模式(http://developer.android.com/reference/android/os/StrictMode.html)以确保您已完成所有操作(如果您在UI线程上执行某些操作,则不会向您的logcat写入警告):
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
但是,我强烈建议您在处理来自外部来源的图像时使用像凌空或毕加索这样的库。请查看以下问题:Local image caching solution for Android: Square Picasso vs Universal Image Loader
答案 2 :(得分:0)
此代码示例来自我的食谱应用程序,应该说明您的要求。图像作为来自Web服务的base64编码数据读入,因此需要先解码才能在ListView中显示。
代码首先检查缓存图像,如果不是,它使用AsyncTask在后台解码它们,并将结果写入缓存以供将来使用。
解码在doInBackground中完成,缓存的显示/写入在onPostExecute中完成。
这会有所帮助。
mRecipeAdapter = new ArrayAdapter<Recipe>(getActivity(), R.layout.listrow, mData2){
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (null == convertView) {
row = mInflater.inflate(R.layout.recipe_listrow, null);
} else {
row = convertView;
}
TextView tv = (TextView) row.findViewById(R.id.recipe_title);
ImageView iv = (ImageView) row.findViewById(R.id.recipe_image);
iv.setImageBitmap(null);
Recipe r = getItem(position);
tv.setText(r.title);
File cacheFile = new File(mCacheDir, ""+r.identity.hashCode());
if (cacheFile.exists()){
FileInputStream fis;
try {
fis = new FileInputStream(cacheFile);
Bitmap bmp = BitmapFactory.decodeStream(fis);
iv.setImageBitmap(bmp);
bmp = null;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
// Get image asynchronously from database
new AsyncImages(iv).execute(r);
}
return row;
}
class AsyncImages extends AsyncTask<Recipe, Void, Recipe> {
private static final long MAX_SIZE = 5242880L; // 5MB
private final WeakReference<ImageView> imageViewReference;
public AsyncImages(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
protected Recipe doInBackground(Recipe... r) {
Recipe recipe = r[0];
double heapRemaining = Runtime.getRuntime().freeMemory(); //amount available in heap
Log.i("MEM REM", Double.toString(heapRemaining));
String imageString = SchwartzRecipesBaseActivity.getThumbnailImageFor(recipe.identity);
recipe.thumb = StringToBitMap(imageString);
imageString = null;
return recipe;
}
protected void onPostExecute(Recipe r) {
if (isCancelled()) {
r.thumb = null;
return;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(r.thumb);
// Write to cache file
// Make space if needed
long sz = getDirSize();
if (sz>MAX_SIZE){
makeSomeSpace(r.thumb.getByteCount());
}
File cacheFile = new File(mCacheDir, ""+r.identity.hashCode());
try {
// Create a file at the file path, and open it for writing obtaining the output stream
cacheFile.createNewFile();
FileOutputStream fos = new FileOutputStream(cacheFile);
// Write the bitmap to the output stream (and thus the file) in PNG format (lossless compression)
r.thumb.compress(CompressFormat.JPEG, 100, fos);
// Flush and close the output stream
fos.flush();
fos.close();
} catch (Exception e) {
// Log anything that might go wrong with IO to file
Log.e("CACHE", "Error when saving image to cache. ", e);
}
}
}
}
private void makeSomeSpace(long bytes) {
long bytesDeleted = 0;
File[] files = mCacheDir.listFiles();
Arrays.sort(files, new Comparator<File>(){
public int compare(File f1, File f2)
{
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
} });
for (File file : files) {
bytesDeleted += file.length();
file.delete();
if (bytesDeleted >= bytes) {
break;
}
}
}
private long getDirSize() {
if (mCacheDir == null) return 0;
long size = 0;
File[] files = mCacheDir.listFiles();
for (File file : files) {
if (file.isFile()) {
size += file.length();
}
}
return size;
}
}
private Bitmap StringToBitMap(String encodedString) {
try{
byte [] encodeByte=Base64.decode(encodedString,Base64.DEFAULT);
Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
return bitmap;
}catch(Exception e){
e.getMessage();
return null;
}
}
};
setListAdapter(mRecipeAdapter);