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