Skip to content Skip to sidebar Skip to footer

How To Run Sqlite Query Asynchronously On Background Thread?

I have a big database which takes time to find needed information. So I decided to use RxJava to make this process asynchronous. @Override public void afterText

Solution 1:

Probably this https://developer.android.com/reference/android/app/LoaderManager.html will suite for you.

Besides, here is short implementation for you, but this is not RxJava.

Firstly, you need to implement LoaderManager.LoaderCallbacks<Cursor>, and usually this interface is implemented by Activity (or Fragment).

In onCreateLoader, a CursorLoader should be created and returned. Here is just an example with MyCursorLoader as descendant of CursorLoader, where you can perform connection to database and queries.

In onLoadFinished you have to treat cursor with results of query.

Please, consider the link to android.com, mentioned above.

publicclassMainActivityextendsAppCompatActivityimplementsLoaderManager.LoaderCallbacks<Cursor>{

@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@OverrideprotectedvoidonResume() {
    super.onResume();

    // start loading data using LoaderManager of Activity// third argument only has sense in this case
    getLoaderManager().initLoader(0, null, this);
}

privatestaticfinalStringACTIVITY_NAME="main_activity";

privatevoidtreatCursorRow(Cursor cursor){
    // treat record from cursor
}

@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // this callback is called by LoaderManager in order to obtain CursorLoader// here a new one loader is created// created loader will be processed by LoaderManagerreturnnewMyCursorLoader(this, ACTIVITY_NAME);
}

@OverridepublicvoidonLoadFinished(Loader<Cursor> loader, Cursor data) {
    // this callback is called when loader finishes load cursor// you don't need to destroy loader - just tread the dataif(data != null)
        while(data.moveToNext())
            treatCursorRow(data);
}

@OverridepublicvoidonLoaderReset(Loader<Cursor> loader) {
    // here you can do something// relevant to cancelling of loading data// in example, when you have an event that cancels current// loading and restarts new one
}

classMyCursorLoaderextendsCursorLoader {

    privatestaticfinalStringDATABASE_NAME="my_database";
    privatestaticfinalintDATABASE_VERSION=1;
    private String name_param;

    publicMyCursorLoader(Context context, String activity_name) {
        super(context);
        name_param = activity_name;
    }

    @Overridepublic Cursor loadInBackground() {
        // assuming, that we have implemented SQLiteOpenHelper// to treat sqlite-databaseMyDatabaseHelperdbh=newMyDatabaseHelper(
                MainActivity.this,
                DATABASE_NAME,
                null,
                DATABASE_VERSION
        );
        return dbh.getWritableDatabase().rawQuery(
                "SELECT * FROM some_table WHERE name=?",
                newString[]{ name_param }
        );
    }

}

}

Another way, is in using of ContentProviderhttps://developer.android.com/guide/topics/providers/content-providers.html .

In this way you can separate data layer and business logic. Your data access will be abstracted to uris. Using ContentProvider, you define your queries within it and load data using Uri:

@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {
    return getContentResolver().query(
            YourContentProvider.SOME_URI,
            null,
            null,
            null,
            null
    );
}

This is convenient way if you have more than one or two customers of your data (Activities or Fragments) - you will use just predefined uris rather repeating sql queries or creating many CursorLoaders descendands.

Moreover, ContentProvider may be used from outside your app if you want.

Post a Comment for "How To Run Sqlite Query Asynchronously On Background Thread?"