• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.ui;
18 
19 import android.graphics.Bitmap;
20 
21 import com.android.gallery3d.util.Future;
22 import com.android.gallery3d.util.FutureListener;
23 
24 // We use this class to
25 //     1.) load bitmaps in background.
26 //     2.) as a place holder for the loaded bitmap
27 public abstract class BitmapLoader implements FutureListener<Bitmap> {
28     @SuppressWarnings("unused")
29     private static final String TAG = "BitmapLoader";
30 
31     /* Transition Map:
32      *   INIT -> REQUESTED, RECYCLED
33      *   REQUESTED -> INIT (cancel), LOADED, ERROR, RECYCLED
34      *   LOADED, ERROR -> RECYCLED
35      */
36     private static final int STATE_INIT = 0;
37     private static final int STATE_REQUESTED = 1;
38     private static final int STATE_LOADED = 2;
39     private static final int STATE_ERROR = 3;
40     private static final int STATE_RECYCLED = 4;
41 
42     private int mState = STATE_INIT;
43     // mTask is not null only when a task is on the way
44     private Future<Bitmap> mTask;
45     private Bitmap mBitmap;
46 
47     @Override
onFutureDone(Future<Bitmap> future)48     public void onFutureDone(Future<Bitmap> future) {
49         synchronized (this) {
50             mTask = null;
51             mBitmap = future.get();
52             if (mState == STATE_RECYCLED) {
53                 if (mBitmap != null) {
54                     recycleBitmap(mBitmap);
55                     mBitmap = null;
56                 }
57                 return; // don't call callback
58             }
59             if (future.isCancelled() && mBitmap == null) {
60                 if (mState == STATE_REQUESTED) mTask = submitBitmapTask(this);
61                 return; // don't call callback
62             } else {
63                 mState = mBitmap == null ? STATE_ERROR : STATE_LOADED;
64             }
65         }
66         onLoadComplete(mBitmap);
67     }
68 
startLoad()69     public synchronized void startLoad() {
70         if (mState == STATE_INIT) {
71             mState = STATE_REQUESTED;
72             if (mTask == null) mTask = submitBitmapTask(this);
73         }
74     }
75 
cancelLoad()76     public synchronized void cancelLoad() {
77         if (mState == STATE_REQUESTED) {
78             mState = STATE_INIT;
79             if (mTask != null) mTask.cancel();
80         }
81     }
82 
83     // Recycle the loader and the bitmap
recycle()84     public synchronized void recycle() {
85         mState = STATE_RECYCLED;
86         if (mBitmap != null) {
87             recycleBitmap(mBitmap);
88             mBitmap = null;
89         }
90         if (mTask != null) mTask.cancel();
91     }
92 
isRequestInProgress()93     public synchronized boolean isRequestInProgress() {
94         return mState == STATE_REQUESTED;
95     }
96 
isRecycled()97     public synchronized boolean isRecycled() {
98         return mState == STATE_RECYCLED;
99     }
100 
getBitmap()101     public synchronized Bitmap getBitmap() {
102         return mBitmap;
103     }
104 
submitBitmapTask(FutureListener<Bitmap> l)105     abstract protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l);
recycleBitmap(Bitmap bitmap)106     abstract protected void recycleBitmap(Bitmap bitmap);
onLoadComplete(Bitmap bitmap)107     abstract protected void onLoadComplete(Bitmap bitmap);
108 }
109