From e29d4546db20056f77e3e98633d23565a71b50bd Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Wed, 23 Apr 2014 00:11:13 -0400 Subject: [PATCH] Refactor so we don't re-download the book list every time Code is still pretty ugly, but I'm not sure on how to prettify it. Get to that later. --- .../downloader/BookListFragment.java | 17 +++-- .../downloader/BookRefreshTask.java | 55 ++++++++++----- .../downloader/DownloadManager.java | 70 ++++++++++++------- .../downloader/NoopBookRefreshTask.java | 25 +++++++ 4 files changed, 114 insertions(+), 53 deletions(-) create mode 100644 MinimalBible/src/org/bspeice/minimalbible/activities/downloader/NoopBookRefreshTask.java diff --git a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookListFragment.java b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookListFragment.java index b0daea1..a95d4dd 100644 --- a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookListFragment.java +++ b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookListFragment.java @@ -120,18 +120,17 @@ public class BookListFragment extends Fragment { f = null; break; } - DownloadManager dm = new DownloadManager(); - - ProgressDialog refreshDialog = new ProgressDialog(getActivity()); - if (dm.willRefresh()) { + DownloadManager dm = DownloadManager.getInstance(); + + if (!dm.isLoaded()) { + ProgressDialog refreshDialog = new ProgressDialog(getActivity()); refreshDialog.setMessage("Refreshing available modules..."); + refreshDialog.setCancelable(false); + refreshDialog.show(); + dm.fetchAvailableBooks(f, new DlBookRefreshListener(refreshDialog)); } else { - refreshDialog - .setMessage("Fetching available modules from cache..."); + dm.fetchAvailableBooks(f, new DlBookRefreshListener(null)); } - refreshDialog.setCancelable(false); - refreshDialog.show(); - dm.fetchAvailableBooks(f, new DlBookRefreshListener(refreshDialog)); } private class DlBookRefreshListener implements diff --git a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookRefreshTask.java b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookRefreshTask.java index 86f8795..154cf59 100644 --- a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookRefreshTask.java +++ b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/BookRefreshTask.java @@ -3,29 +3,31 @@ package org.bspeice.minimalbible.activities.downloader; import java.util.LinkedList; import java.util.List; +import org.bspeice.minimalbible.MinimalBible; +import org.bspeice.minimalbible.MinimalBibleConstants; import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.BookFilter; import org.crosswire.jsword.book.install.InstallException; import org.crosswire.jsword.book.install.Installer; +import android.content.Context; +import android.content.SharedPreferences; import android.os.AsyncTask; import android.util.Log; public class BookRefreshTask extends AsyncTask> { - + private static final String TAG = "BookRefreshTask"; - + private BookRefreshListener listener; - private boolean refresh; private BookFilter filter; - - public BookRefreshTask(boolean refresh, BookRefreshListener listener) { - this.refresh = refresh; + + public BookRefreshTask(BookRefreshListener listener) { this.listener = listener; } - - public BookRefreshTask(boolean refresh, BookFilter f, BookRefreshListener listener) { - this.refresh = refresh; + + public BookRefreshTask(BookFilter f, + BookRefreshListener listener) { this.filter = f; this.listener = listener; } @@ -33,35 +35,50 @@ public class BookRefreshTask extends AsyncTask> { @Override protected List doInBackground(Installer... params) { List books = new LinkedList(); - - for (Installer i: params) { - if (refresh) { + + for (Installer i : params) { + if (doRefresh()) { try { i.reloadBookList(); } catch (InstallException e) { - Log.e(TAG, "Error downloading books from installer: " + i.toString(), e); + Log.e(TAG, + "Error downloading books from installer: " + + i.toString(), e); } } - + if (filter != null) { books.addAll(i.getBooks(filter)); } else { books.addAll(i.getBooks()); } } - + return books; } - + + private boolean doRefresh() { + // Check if we should refresh over the internet, or use the local copy + // TODO: Discover if we need to refresh over Internet, or use a cached + // copy - likely something time-based, also check network state. + // Fun fact - jSword handles the caching for us. + + SharedPreferences prefs = MinimalBible.getAppContext() + .getSharedPreferences( + MinimalBibleConstants.DOWNLOAD_PREFS_FILE, + Context.MODE_PRIVATE); + + // Refresh if download enabled + return prefs.getBoolean(MinimalBibleConstants.KEY_DOWNLOAD_ENABLED, false); + } + @Override protected void onPostExecute(List result) { super.onPostExecute(result); listener.onRefreshComplete(result); } - + public interface BookRefreshListener { public void onRefreshComplete(List results); } } - - diff --git a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/DownloadManager.java b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/DownloadManager.java index 0899ab2..2ba56cc 100644 --- a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/DownloadManager.java +++ b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/DownloadManager.java @@ -1,29 +1,36 @@ package org.bspeice.minimalbible.activities.downloader; +import java.util.List; import java.util.Map; import org.bspeice.minimalbible.MinimalBible; -import org.bspeice.minimalbible.MinimalBibleConstants; +import org.bspeice.minimalbible.activities.downloader.BookRefreshTask.BookRefreshListener; +import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.BookCategory; import org.crosswire.jsword.book.BookFilter; import org.crosswire.jsword.book.install.InstallManager; import org.crosswire.jsword.book.install.Installer; -import android.content.Context; -import android.content.SharedPreferences; import android.util.Log; public class DownloadManager { - - // TODO: Probably should be a singleton. private final String TAG = "DownloadManager"; + private static DownloadManager instance; + private List books; public static final BookCategory[] VALID_CATEGORIES = { BookCategory.BIBLE, BookCategory.COMMENTARY, BookCategory.DICTIONARY, BookCategory.IMAGES, BookCategory.MAPS }; - public DownloadManager() { + public static DownloadManager getInstance() { + if (instance == null) { + instance = new DownloadManager(); + } + return instance; + } + + private DownloadManager() { setDownloadDir(); } @@ -31,7 +38,7 @@ public class DownloadManager { BookRefreshTask.BookRefreshListener bookRefreshListener) { return _fetchAvailableBooks(null, bookRefreshListener); } - + public BookRefreshTask fetchAvailableBooks(BookFilter f, BookRefreshTask.BookRefreshListener bookRefreshListener) { return _fetchAvailableBooks(f, bookRefreshListener); @@ -39,32 +46,30 @@ public class DownloadManager { private BookRefreshTask _fetchAvailableBooks(BookFilter f, BookRefreshTask.BookRefreshListener bookRefreshListener) { - - Map installers = getInstallers(); - return (BookRefreshTask) new BookRefreshTask(willRefresh(), - bookRefreshListener).execute(installers.values().toArray( - new Installer[installers.size()])); + if (!isLoaded()) { + return (BookRefreshTask) new BookRefreshTask( + new DmBookRefreshListener(bookRefreshListener)) + .execute(getInstallersArray()); + } else { + return (BookRefreshTask) new NoopBookRefreshTask(books, + bookRefreshListener).execute(getInstallersArray()); + } } - public boolean willRefresh() { - // Method to determine if we need a refresh - // Public, so other modules can predict and take action accordingly. - // TODO: Discover if we need to refresh over Internet, or use a cached - // copy - likely something time-based, also check network state. - // Fun fact - jSword handles the caching for us. - - SharedPreferences prefs = MinimalBible.getAppContext() - .getSharedPreferences( - MinimalBibleConstants.DOWNLOAD_PREFS_FILE, - Context.MODE_PRIVATE); - - return (prefs.getBoolean(MinimalBibleConstants.KEY_DOWNLOAD_ENABLED, false)); + public boolean isLoaded() { + // Let methods know if we're going to take a while to reload everything + return (books != null); } public Map getInstallers() { return new InstallManager().getInstallers(); } + + public Installer[] getInstallersArray() { + Map installers = getInstallers(); + return installers.values().toArray(new Installer[installers.size()]); + } private void setDownloadDir() { // We need to set the download directory for jSword to stick with @@ -74,4 +79,19 @@ public class DownloadManager { System.setProperty("jsword.home", home); } + // Create our own refresh listener to save a reference to the books + private class DmBookRefreshListener implements BookRefreshListener { + private BookRefreshListener listener; + + public DmBookRefreshListener(BookRefreshListener listener) { + this.listener = listener; + } + + @Override + public void onRefreshComplete(List results) { + books = results; + listener.onRefreshComplete(results); + } + } + } diff --git a/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/NoopBookRefreshTask.java b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/NoopBookRefreshTask.java new file mode 100644 index 0000000..6d732af --- /dev/null +++ b/MinimalBible/src/org/bspeice/minimalbible/activities/downloader/NoopBookRefreshTask.java @@ -0,0 +1,25 @@ +package org.bspeice.minimalbible.activities.downloader; + +import java.util.List; + +import org.crosswire.jsword.book.Book; +import org.crosswire.jsword.book.install.Installer; + +/* + * There's probably a better way of doing this, but this allows me to avoid networking, + * while still maintaining the code structure of being asynchronous. + */ +public class NoopBookRefreshTask extends BookRefreshTask { + BookRefreshListener listener; + List books; + + public NoopBookRefreshTask(List books, BookRefreshListener listener) { + super(listener); + this.books = books; + } + + @Override + protected List doInBackground(Installer... params) { + return books; + } +}