使用LoaderCallbacks时,是否必须使用Content Provider?

时间:2014-03-17 17:58:41

标签: android android-contentprovider android-cursorloader

CursorLoader需要URI的参数,这是需要的Content Provider。 我可以在没有ContentProvider的情况下使用CursorLoader吗? 感谢。

1 个答案:

答案 0 :(得分:0)

CursorLoader想要一个ContentProvider,但你可以创建自己的CursorLoader来扩展AsyncTaskLoader

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.v4.content.AsyncTaskLoader;

public class CursorLoader extends AsyncTaskLoader<Cursor> {
  final ForceLoadContentObserver mObserver;
  SQLiteDatabase     mDatabase;
  String            mSQL;
  String[]        mSelectionArgs;
  Cursor mCursor;

  /* Runs on a worker thread */
  @Override
  public Cursor loadInBackground() {
    if (mDatabase == null) return null;
    Cursor cursor = mDatabase.rawQuery(mSQL, mSelectionArgs);
    if (cursor != null) {
        // Ensure the cursor window is filled
        cursor.getCount();
        registerContentObserver(cursor, mObserver);
    }
    return cursor;
  }

  /**
   * Registers an observer to get notifications from the content provider
   * when the cursor needs to be refreshed.
   */
  void registerContentObserver(Cursor cursor, ContentObserver observer) {
    cursor.registerContentObserver(mObserver);
  }

  /* Runs on the UI thread */
  @Override
  public void deliverResult(Cursor cursor) {
    if (isReset()) {
        // An async query came in while the loader is stopped
        if (cursor != null) {
            cursor.close();
        }
        return;
    }
    Cursor oldCursor = mCursor;
    mCursor = cursor;
    if (isStarted()) {
        super.deliverResult(cursor);
    }
    if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
        oldCursor.close();
    }
  }

  public CursorLoader(Context context) {
    super(context);
    mObserver = new ForceLoadContentObserver();
    mSQL = null;
    mSelectionArgs = null;
  }

  public CursorLoader(Context context, String sql, String[] selectionArgs) {
    super(context);
    mObserver = new ForceLoadContentObserver();
    mSQL = sql;
    mSelectionArgs = selectionArgs;
  }

  @Override
  protected void onStartLoading() {
    if (mCursor != null) {
        deliverResult(mCursor);
    }
    if (takeContentChanged() || mCursor == null) {
        forceLoad();
    }
  }

  @Override
  protected void onStopLoading() {
    // Attempt to cancel the current load task if possible.
    cancelLoad();
  }

  @Override
  public void onCanceled(Cursor cursor) {
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
    }
  }

 @Override
 protected void onReset() {
    super.onReset();
    onStopLoading();
    if (mCursor != null && !mCursor.isClosed()) {
        mCursor.close();
    }
    mCursor = null;
 }

 public String getSql() { return mSQL; }
 public void setSQL(final String value) { mSQL = value; }
 public String[] getSelectionArgs() { return mSelectionArgs; }
 public void setSelectionArgs(String[] selectionArgs) { 
   mSelectionArgs = selectionArgs; 
 }

 public void setDatabase(final SQLiteDatabase value) { mDatabase = value; }

 @Override
 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
    super.dump(prefix, fd, writer, args);
    writer.print(prefix); writer.print("mSQL="); writer.println(mSQL);
    writer.print(prefix); writer.print("mSelectionArgs=");
    writer.println(Arrays.toString(mSelectionArgs));
 }

}

使用它:

CursorLoader loader = new CursorLoader(getActivity());
loader.setDatabase(SchemaHelper.getInstance(getActivity()).getReadableDatabase());
loader.setSQL(MY_SQL_STRING);
loader.setSelectionArgs(MY_SELECTION_ARGS);
return loader