michael@0: /* michael@0: * This is an adapted version of Android's original CursorLoader michael@0: * without all the ContentProvider-specific bits. michael@0: * michael@0: * Copyright (C) 2011 The Android Open Source Project michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: package org.mozilla.gecko.home; michael@0: michael@0: import android.content.Context; michael@0: import android.database.Cursor; michael@0: import android.support.v4.content.AsyncTaskLoader; michael@0: michael@0: abstract class SimpleCursorLoader extends AsyncTaskLoader { michael@0: final ForceLoadContentObserver mObserver; michael@0: Cursor mCursor; michael@0: michael@0: public SimpleCursorLoader(Context context) { michael@0: super(context); michael@0: mObserver = new ForceLoadContentObserver(); michael@0: } michael@0: michael@0: /** michael@0: * Loads the target cursor for this loader. This method is called michael@0: * on a worker thread. michael@0: */ michael@0: protected abstract Cursor loadCursor(); michael@0: michael@0: /* Runs on a worker thread */ michael@0: @Override michael@0: public Cursor loadInBackground() { michael@0: Cursor cursor = loadCursor(); michael@0: michael@0: if (cursor != null) { michael@0: // Ensure the cursor window is filled michael@0: cursor.getCount(); michael@0: cursor.registerContentObserver(mObserver); michael@0: } michael@0: michael@0: return cursor; michael@0: } michael@0: michael@0: /* Runs on the UI thread */ michael@0: @Override michael@0: public void deliverResult(Cursor cursor) { michael@0: if (isReset()) { michael@0: // An async query came in while the loader is stopped michael@0: if (cursor != null) { michael@0: cursor.close(); michael@0: } michael@0: michael@0: return; michael@0: } michael@0: michael@0: Cursor oldCursor = mCursor; michael@0: mCursor = cursor; michael@0: michael@0: if (isStarted()) { michael@0: super.deliverResult(cursor); michael@0: } michael@0: michael@0: if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { michael@0: oldCursor.close(); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Starts an asynchronous load of the list data. When the result is ready the callbacks michael@0: * will be called on the UI thread. If a previous load has been completed and is still valid michael@0: * the result may be passed to the callbacks immediately. michael@0: * michael@0: * Must be called from the UI thread michael@0: */ michael@0: @Override michael@0: protected void onStartLoading() { michael@0: if (mCursor != null) { michael@0: deliverResult(mCursor); michael@0: } michael@0: michael@0: if (takeContentChanged() || mCursor == null) { michael@0: forceLoad(); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Must be called from the UI thread michael@0: */ michael@0: @Override michael@0: protected void onStopLoading() { michael@0: // Attempt to cancel the current load task if possible. michael@0: cancelLoad(); michael@0: } michael@0: michael@0: @Override michael@0: public void onCanceled(Cursor cursor) { michael@0: if (cursor != null && !cursor.isClosed()) { michael@0: cursor.close(); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: protected void onReset() { michael@0: super.onReset(); michael@0: michael@0: // Ensure the loader is stopped michael@0: onStopLoading(); michael@0: michael@0: if (mCursor != null && !mCursor.isClosed()) { michael@0: mCursor.close(); michael@0: } michael@0: michael@0: mCursor = null; michael@0: } michael@0: }