ThumbnailLoadTask.java revision 2ea06183aa826b28fe6ebdb454da49ba3878bc4f
1/* 2 * Copyright (C) 2012 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mail.ui; 19 20import android.content.res.AssetFileDescriptor; 21import android.graphics.Bitmap; 22import android.graphics.BitmapFactory; 23import android.net.Uri; 24import android.os.AsyncTask; 25 26import com.android.mail.providers.Attachment; 27import com.android.mail.utils.LogUtils; 28 29import java.io.IOException; 30 31/** 32 * Performs the load of a thumbnail bitmap in a background 33 * {@link AsyncTask}. Available for use with any view that implements 34 * the {@link AttachmentBitmapHolder} interface. 35 */ 36public class ThumbnailLoadTask extends AsyncTask<Uri, Void, Bitmap> { 37 private static final String LOG_TAG = new LogUtils().getLogTag(); 38 39 private final AttachmentBitmapHolder mHolder; 40 private final int mWidth; 41 private final int mHeight; 42 43 public static void setupThumbnailPreview( 44 ThumbnailLoadTask task, AttachmentBitmapHolder holder, 45 Attachment attachment, final Attachment prevAttachment) { 46 if (attachment == null) { 47 holder.setThumbnailToDefault(); 48 return; 49 } 50 51 final Uri imageUri = attachment.getImageUri(); 52 final Uri prevImageUri = (prevAttachment == null) ? null : prevAttachment.getImageUri(); 53 // begin loading a thumbnail if this is an image and either the thumbnail or the original 54 // content is ready (and different from any existing image) 55 if (imageUri != null && (prevImageUri == null || !imageUri.equals(prevImageUri))) { 56 // cancel/dispose any existing task and start a new one 57 if (task != null) { 58 task.cancel(true); 59 } 60 task = new ThumbnailLoadTask( 61 holder, holder.getThumbnailWidth(), holder.getThumbnailHeight()); 62 task.execute(imageUri); 63 } else if (imageUri == null) { 64 // not an image, or no thumbnail exists. fall back to default. 65 // async image load must separately ensure the default appears upon load failure. 66 holder.setThumbnailToDefault(); 67 } 68 } 69 70 public ThumbnailLoadTask(AttachmentBitmapHolder holder, int width, int height) { 71 mHolder = holder; 72 mWidth = width; 73 mHeight = height; 74 } 75 76 @Override 77 protected Bitmap doInBackground(Uri... params) { 78 final Uri thumbnailUri = params[0]; 79 80 AssetFileDescriptor fd = null; 81 Bitmap result = null; 82 83 try { 84 fd = mHolder.getResolver().openAssetFileDescriptor(thumbnailUri, "r"); 85 if (isCancelled() || fd == null) { 86 return null; 87 } 88 89 final BitmapFactory.Options opts = new BitmapFactory.Options(); 90 opts.inJustDecodeBounds = true; 91 92 BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, opts); 93 if (isCancelled() || opts.outWidth == -1 || opts.outHeight == -1) { 94 return null; 95 } 96 97 opts.inJustDecodeBounds = false; 98 99 LogUtils.d(LOG_TAG, "in background, src w/h=%d/%d dst w/h=%d/%d, divider=%d", 100 opts.outWidth, opts.outHeight, mWidth, mHeight, opts.inSampleSize); 101 102 result = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, opts); 103 104 } catch (Throwable t) { 105 LogUtils.e(LOG_TAG, t, "Unable to decode thumbnail %s", thumbnailUri); 106 } finally { 107 if (fd != null) { 108 try { 109 fd.close(); 110 } catch (IOException e) { 111 LogUtils.e(LOG_TAG, e, ""); 112 } 113 } 114 } 115 116 return result; 117 } 118 119 @Override 120 protected void onPostExecute(Bitmap result) { 121 if (result == null) { 122 LogUtils.d(LOG_TAG, "back in UI thread, decode failed"); 123 mHolder.setThumbnailToDefault(); 124 return; 125 } 126 127 LogUtils.d(LOG_TAG, "back in UI thread, decode success, w/h=%d/%d", result.getWidth(), 128 result.getHeight()); 129 mHolder.setThumbnail(result); 130 } 131 132} 133