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