Skip to content

Commit

Permalink
Use AsyncTask plus Lifecycle object instead of Loader
Browse files Browse the repository at this point in the history
Loaders have now been deprecated in favor of the lifecycle support library
  • Loading branch information
timrae committed Sep 16, 2018
1 parent fe1f03e commit cb76f00
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 93 deletions.
60 changes: 17 additions & 43 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
Expand All @@ -38,8 +36,7 @@

import timber.log.Timber;

public class AnkiActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Collection>,
SimpleMessageDialog.SimpleMessageDialogListener {
public class AnkiActivity extends AppCompatActivity implements SimpleMessageDialog.SimpleMessageDialogListener {

public final int SIMPLE_NOTIFICATION_ID = 0;
public static final int REQUEST_REVIEW = 901;
Expand Down Expand Up @@ -97,6 +94,7 @@ public boolean onOptionsItemSelected(MenuItem item) {

// called when the CollectionLoader finishes... usually will be over-ridden
protected void onCollectionLoaded(Collection col) {
hideProgressBar();
}


Expand Down Expand Up @@ -250,49 +248,25 @@ private void enableActivityAnimation(int animation) {

// Method for loading the collection which is inherited by all AnkiActivitys
public void startLoadingCollection() {
// Initialize the open collection loader
Timber.d("AnkiActivity.startLoadingCollection()");
if (!colIsOpen()) {
showProgressBar();
if (colIsOpen()) {
onCollectionLoaded(getCol());
return;
}
getSupportLoaderManager().restartLoader(0, null, this);
}


// Kick user back to DeckPicker on collection load error unless this method is overridden
protected void onCollectionLoadError() {
Intent deckPicker = new Intent(this, DeckPicker.class);
deckPicker.putExtra("collectionLoadError", true); // don't currently do anything with this
deckPicker.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityWithAnimation(deckPicker, ActivityTransitionAnimation.LEFT);
}


// CollectionLoader Listener callbacks
@Override
public Loader<Collection> onCreateLoader(int id, Bundle args) {
// Currently only using one loader, so ignore id
return new CollectionLoader(this);
}


@Override
public void onLoadFinished(Loader<Collection> loader, Collection col) {
hideProgressBar();
if (col != null && colIsOpen()) {
onCollectionLoaded(col);
} else {
onCollectionLoadError();
}
}


@Override
public void onLoaderReset(Loader<Collection> arg0) {
// We don't currently retain any references, so no need to free any data here
// Open collection asynchronously if it hasn't already been opened
showProgressBar();
CollectionLoader.load(this, col -> {
if (col != null) {
onCollectionLoaded(col);
} else {
Intent deckPicker = new Intent(this, DeckPicker.class);
deckPicker.putExtra("collectionLoadError", true); // don't currently do anything with this
deckPicker.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityWithAnimation(deckPicker, ActivityTransitionAnimation.LEFT);
}
});
}


public void showProgressBar() {
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
if (progressBar != null) {
Expand Down
10 changes: 4 additions & 6 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ private void onFinishedStartup() {
getCol().modSchema();
} catch (ConfirmModSchemaException e) {
// If libanki determines it's necessary to confirm the full sync then show a confirmation dialog
// We have to show the dialog via the DialogHandler since this method is called via a Loader
// We have to show the dialog via the DialogHandler since this method is called via an async task
Resources res = getResources();
Message handlerMessage = Message.obtain();
handlerMessage.what = DialogHandler.MSG_SHOW_FORCE_FULL_SYNC_DIALOG;
Expand All @@ -841,12 +841,10 @@ private void onFinishedStartup() {
automaticSync();
}

@Override
protected void onCollectionLoadError() {
private void showCollectionErrorDialog() {
getDialogHandler().sendEmptyMessage(DialogHandler.MSG_SHOW_COLLECTION_LOADING_ERROR_DIALOG);
}


public void addNote() {
Intent intent = new Intent(DeckPicker.this, NoteEditor.class);
intent.putExtra(NoteEditor.EXTRA_CALLER, NoteEditor.CALLER_DECKPICKER);
Expand Down Expand Up @@ -1144,7 +1142,7 @@ public void onPostExecute(DeckTask.TaskData result) {
}
if (result == null || !result.getBoolean()) {
UIUtils.showThemedToast(DeckPicker.this, getResources().getString(R.string.deck_repair_error), true);
onCollectionLoadError();
showCollectionErrorDialog();
}
}

Expand Down Expand Up @@ -1871,7 +1869,7 @@ public void onPostExecute(TaskData result) {
}
if (result == null) {
Timber.e("null result loading deck counts");
onCollectionLoadError();
showCollectionErrorDialog();
return;
}
List<Sched.DeckDueTreeNode> nodes = (List<Sched.DeckDueTreeNode>) result.getObjArray()[0];
Expand Down
75 changes: 31 additions & 44 deletions AnkiDroid/src/main/java/com/ichi2/async/CollectionLoader.java
Original file line number Diff line number Diff line change
@@ -1,70 +1,57 @@
package com.ichi2.async;

import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleOwner;
import android.os.AsyncTask;

import com.ichi2.anki.AnkiDroidApp;
import com.ichi2.anki.CollectionHelper;
import com.ichi2.libanki.Collection;

import timber.log.Timber;

public class CollectionLoader extends AsyncTaskLoader<Collection> {
public final class CollectionLoader extends AsyncTask<Void, Void, Collection> {
public interface Callback {
void execute(Collection col);
}

private LifecycleOwner mLifecycleOwner;
private Callback mCallback;

public static void load(LifecycleOwner lifecycleOwner, Callback callback) {
CollectionLoader loader = new CollectionLoader(lifecycleOwner, callback);
loader.execute();
}

public CollectionLoader(Context context) {
super(context);
private CollectionLoader(LifecycleOwner lifecycleOwner, Callback callback) {
mLifecycleOwner = lifecycleOwner;
mCallback = callback;
}

@Override
public Collection loadInBackground() {
protected Collection doInBackground(Void... params) {
// Don't touch collection if lockCollection flag is set
if (CollectionHelper.getInstance().isCollectionLocked()) {
Timber.w("onStartLoading() :: Another thread has requested to keep the collection closed.");
return null;
}
// load collection
try {
Timber.d("CollectionLoader accessing collection");
return CollectionHelper.getInstance().getCol(getContext());
return CollectionHelper.getInstance().getCol(AnkiDroidApp.getInstance().getApplicationContext());
} catch (RuntimeException e) {
Timber.e(e, "loadInBackground - RuntimeException on opening collection");
AnkiDroidApp.sendExceptionReport(e, "CollectionLoader.loadInBackground");
return null;
}
}

@Override
public void deliverResult(Collection col) {
Timber.d("CollectionLoader.deliverResult()");
// Loader has been reset so don't forward data to listener
if (isReset()) {
if (col != null) {
return;
}
}
// Loader is running so forward data to listener
if (isStarted()) {
super.deliverResult(col);
}
}


@Override
protected void onStartLoading() {
// Don't touch collection if lockCollection flag is set
if (CollectionHelper.getInstance().isCollectionLocked()) {
Timber.w("onStartLoading() :: Another thread has requested to keep the collection closed.");
return;
protected void onPostExecute(Collection col) {
super.onPostExecute(col);
if (mLifecycleOwner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) {
mCallback.execute(col);
}
// Since the CollectionHelper only opens if necessary, we can just force every time
forceLoad();
}

@Override
protected void onStopLoading() {
// The Loader has been put in a stopped state, so we should attempt to cancel the current load (if there is one).
Timber.d("CollectionLoader.onStopLoading()");
cancelLoad();
}

@Override
protected void onReset() {
// Ensure the loader is stopped.
Timber.d("CollectionLoader.onReset()");
onStopLoading();
}

}

0 comments on commit cb76f00

Please # to comment.