PhotoBitmapLoader.java revision 3a14814364ff1e48109d32a06bd063c66914889b
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            bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM);
56            return bitmap;
57        }
58
59        return null;
60    }
61
62    /**
63     * Called when there is new data to deliver to the client.  The
64     * super class will take care of delivering it; the implementation
65     * here just adds a little more logic.
66     */
67    @Override
68    public void deliverResult(Bitmap bitmap) {
69        if (isReset()) {
70            // An async query came in while the loader is stopped.  We
71            // don't need the result.
72            if (bitmap != null) {
73                onReleaseResources(bitmap);
74            }
75        }
76        Bitmap oldBitmap = mBitmap;
77        mBitmap = bitmap;
78
79        if (isStarted()) {
80            // If the Loader is currently started, we can immediately
81            // deliver its results.
82            super.deliverResult(bitmap);
83        }
84
85        // At this point we can release the resources associated with
86        // 'oldBitmap' if needed; now that the new result is delivered we
87        // know that it is no longer in use.
88        if (oldBitmap != null && oldBitmap != bitmap && !oldBitmap.isRecycled()) {
89            onReleaseResources(oldBitmap);
90        }
91    }
92
93    /**
94     * Handles a request to start the Loader.
95     */
96    @Override
97    protected void onStartLoading() {
98        if (mBitmap != null) {
99            // If we currently have a result available, deliver it
100            // immediately.
101            deliverResult(mBitmap);
102        }
103
104        if (takeContentChanged() || mBitmap == null) {
105            // If the data has changed since the last time it was loaded
106            // or is not currently available, start a load.
107            forceLoad();
108        }
109    }
110
111    /**
112     * Handles a request to stop the Loader.
113     */
114    @Override protected void onStopLoading() {
115        // Attempt to cancel the current load task if possible.
116        cancelLoad();
117    }
118
119    /**
120     * Handles a request to cancel a load.
121     */
122    @Override
123    public void onCanceled(Bitmap bitmap) {
124        super.onCanceled(bitmap);
125
126        // At this point we can release the resources associated with 'bitmap'
127        // if needed.
128        onReleaseResources(bitmap);
129    }
130
131    /**
132     * Handles a request to completely reset the Loader.
133     */
134    @Override
135    protected void onReset() {
136        super.onReset();
137
138        // Ensure the loader is stopped
139        onStopLoading();
140
141        // At this point we can release the resources associated with 'bitmap'
142        // if needed.
143        if (mBitmap != null) {
144            onReleaseResources(mBitmap);
145            mBitmap = null;
146        }
147    }
148
149    /**
150     * Helper function to take care of releasing resources associated
151     * with an actively loaded data set.
152     */
153    protected void onReleaseResources(Bitmap bitmap) {
154        if (bitmap != null && !bitmap.isRecycled()) {
155            bitmap.recycle();
156        }
157    }
158}
159