1/* 2 * Copyright (C) 2011 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.ex.photo.loaders; 19 20import android.content.AsyncTaskLoader; 21import android.content.ContentResolver; 22import android.content.Context; 23import android.graphics.Bitmap; 24import android.net.Uri; 25import android.util.DisplayMetrics; 26 27import com.android.ex.photo.fragments.PhotoViewFragment; 28import com.android.ex.photo.util.ImageUtils; 29 30/** 31 * Loader for the bitmap of a photo. 32 */ 33public class PhotoBitmapLoader extends AsyncTaskLoader<Bitmap> { 34 private String mPhotoUri; 35 36 private Bitmap mBitmap; 37 38 public PhotoBitmapLoader(Context context, String photoUri) { 39 super(context); 40 mPhotoUri = photoUri; 41 } 42 43 public void setPhotoUri(String photoUri) { 44 mPhotoUri = photoUri; 45 } 46 47 @Override 48 public Bitmap loadInBackground() { 49 Context context = getContext(); 50 51 if (context != null && mPhotoUri != null) { 52 final ContentResolver resolver = context.getContentResolver(); 53 Bitmap bitmap = ImageUtils.createLocalBitmap(resolver, Uri.parse(mPhotoUri), 54 PhotoViewFragment.sPhotoSize); 55 if (bitmap != null) { 56 bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM); 57 } 58 return bitmap; 59 } 60 61 return null; 62 } 63 64 /** 65 * Called when there is new data to deliver to the client. The 66 * super class will take care of delivering it; the implementation 67 * here just adds a little more logic. 68 */ 69 @Override 70 public void deliverResult(Bitmap bitmap) { 71 if (isReset()) { 72 // An async query came in while the loader is stopped. We 73 // don't need the result. 74 if (bitmap != null) { 75 onReleaseResources(bitmap); 76 } 77 } 78 Bitmap oldBitmap = mBitmap; 79 mBitmap = bitmap; 80 81 if (isStarted()) { 82 // If the Loader is currently started, we can immediately 83 // deliver its results. 84 super.deliverResult(bitmap); 85 } 86 87 // At this point we can release the resources associated with 88 // 'oldBitmap' if needed; now that the new result is delivered we 89 // know that it is no longer in use. 90 if (oldBitmap != null && oldBitmap != bitmap && !oldBitmap.isRecycled()) { 91 onReleaseResources(oldBitmap); 92 } 93 } 94 95 /** 96 * Handles a request to start the Loader. 97 */ 98 @Override 99 protected void onStartLoading() { 100 if (mBitmap != null) { 101 // If we currently have a result available, deliver it 102 // immediately. 103 deliverResult(mBitmap); 104 } 105 106 if (takeContentChanged() || mBitmap == null) { 107 // If the data has changed since the last time it was loaded 108 // or is not currently available, start a load. 109 forceLoad(); 110 } 111 } 112 113 /** 114 * Handles a request to stop the Loader. 115 */ 116 @Override protected void onStopLoading() { 117 // Attempt to cancel the current load task if possible. 118 cancelLoad(); 119 } 120 121 /** 122 * Handles a request to cancel a load. 123 */ 124 @Override 125 public void onCanceled(Bitmap bitmap) { 126 super.onCanceled(bitmap); 127 128 // At this point we can release the resources associated with 'bitmap' 129 // if needed. 130 onReleaseResources(bitmap); 131 } 132 133 /** 134 * Handles a request to completely reset the Loader. 135 */ 136 @Override 137 protected void onReset() { 138 super.onReset(); 139 140 // Ensure the loader is stopped 141 onStopLoading(); 142 143 // At this point we can release the resources associated with 'bitmap' 144 // if needed. 145 if (mBitmap != null) { 146 onReleaseResources(mBitmap); 147 mBitmap = null; 148 } 149 } 150 151 /** 152 * Helper function to take care of releasing resources associated 153 * with an actively loaded data set. 154 */ 155 protected void onReleaseResources(Bitmap bitmap) { 156 if (bitmap != null && !bitmap.isRecycled()) { 157 bitmap.recycle(); 158 } 159 } 160} 161