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