2014-09-24 13:54:56 -07:00
|
|
|
package org.thoughtcrime.securesms.util;
|
|
|
|
|
2018-01-04 11:11:49 -08:00
|
|
|
import android.annotation.SuppressLint;
|
2014-09-24 13:54:56 -07:00
|
|
|
import android.content.Context;
|
|
|
|
import android.database.Cursor;
|
2020-08-19 10:06:26 +10:00
|
|
|
import androidx.loader.content.AsyncTaskLoader;
|
2014-09-24 13:54:56 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A Loader similar to CursorLoader that doesn't require queries to go through the ContentResolver
|
|
|
|
* to get the benefits of reloading when content has changed.
|
|
|
|
*/
|
|
|
|
public abstract class AbstractCursorLoader extends AsyncTaskLoader<Cursor> {
|
2018-01-04 11:11:49 -08:00
|
|
|
|
|
|
|
@SuppressWarnings("unused")
|
2014-09-24 13:54:56 -07:00
|
|
|
private static final String TAG = AbstractCursorLoader.class.getSimpleName();
|
|
|
|
|
2018-01-04 11:11:49 -08:00
|
|
|
@SuppressLint("StaticFieldLeak")
|
2014-09-24 13:54:56 -07:00
|
|
|
protected final Context context;
|
2018-01-04 11:11:49 -08:00
|
|
|
private final ForceLoadContentObserver observer;
|
2014-09-24 13:54:56 -07:00
|
|
|
protected Cursor cursor;
|
|
|
|
|
|
|
|
public AbstractCursorLoader(Context context) {
|
|
|
|
super(context);
|
|
|
|
this.context = context.getApplicationContext();
|
|
|
|
this.observer = new ForceLoadContentObserver();
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract Cursor getCursor();
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void deliverResult(Cursor newCursor) {
|
|
|
|
if (isReset()) {
|
|
|
|
if (newCursor != null) {
|
|
|
|
newCursor.close();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Cursor oldCursor = this.cursor;
|
|
|
|
|
|
|
|
this.cursor = newCursor;
|
|
|
|
|
|
|
|
if (isStarted()) {
|
|
|
|
super.deliverResult(newCursor);
|
|
|
|
}
|
|
|
|
if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
|
|
|
|
oldCursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStartLoading() {
|
|
|
|
if (cursor != null) {
|
|
|
|
deliverResult(cursor);
|
|
|
|
}
|
|
|
|
if (takeContentChanged() || cursor == null) {
|
|
|
|
forceLoad();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStopLoading() {
|
|
|
|
cancelLoad();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCanceled(Cursor cursor) {
|
|
|
|
if (cursor != null && !cursor.isClosed()) {
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Cursor loadInBackground() {
|
|
|
|
Cursor newCursor = getCursor();
|
|
|
|
if (newCursor != null) {
|
|
|
|
newCursor.getCount();
|
|
|
|
newCursor.registerContentObserver(observer);
|
|
|
|
}
|
|
|
|
return newCursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onReset() {
|
|
|
|
super.onReset();
|
|
|
|
|
|
|
|
onStopLoading();
|
|
|
|
|
|
|
|
if (cursor != null && !cursor.isClosed()) {
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
cursor = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|