From ba3c6ebe6c1f203da28cfd98806cc51256d0efa5 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Sat, 14 Jun 2014 14:08:50 -0400 Subject: [PATCH] Some refactoring and Async fixes. --- .../downloader/BookListFragment.java | 53 +++++++++---------- .../downloader/DownloadActivity.java | 1 + .../downloader/manager/RefreshManager.java | 9 ++-- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/BookListFragment.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/BookListFragment.java index b668b8a..90d01cd 100644 --- a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/BookListFragment.java +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/BookListFragment.java @@ -5,6 +5,7 @@ import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; +import android.os.Looper; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -30,6 +31,7 @@ import javax.inject.Inject; import butterknife.ButterKnife; import butterknife.InjectView; +import rx.Observable; import rx.android.schedulers.AndroidSchedulers; /** @@ -125,38 +127,31 @@ public class BookListFragment extends BaseFragment { } // Listen for the books! - refreshManager.getAvailableModules().subscribeOn(AndroidSchedulers.mainThread()) - .reduce(new ArrayList(), (books, installerListMap) -> { - for (List l : installerListMap.values()) { - books.addAll(l); + refreshManager.getAvailableModules() + // First flatten the Map to its lists + .flatMap((books) -> Observable.from(books.values())) + // Then flatten the lists + .flatMap((books) -> Observable.from(books)) + .filter((book) -> book.getBookCategory() == + BookCategory.fromString(getArguments().getString(ARG_BOOK_CATEGORY))) + // Repack all the books + .toSortedList((book1, book2) -> + BookComparators.getInitialComparator().compare(book1, book2)) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((books) -> { + downloadsAvailable.setAdapter(new BookListAdapter(inflater, books)); + if (getActivity() != null) { + // On a screen rotate, getActivity() will be null. But, the activity will + // already have been set up correctly, so we don't need to worry about it. + // If not null, we need to set it up now. + setInsets(getActivity(), downloadsAvailable); } - return books; - }).take(1) - .subscribe((books) -> displayBooks(books)); + if (refreshDialog != null) { + refreshDialog.cancel(); + } + }); } - /** - * Do the hard work of creating the Adapter and displaying books. - * @param bookList The (unfiltered) list of {link org.crosswire.jsword.Book}s to display - */ - public void displayBooks(List bookList) { - try { - // TODO: Should the filter be applied earlier in the process? - List displayList; - - BookCategory c = BookCategory.fromString(getArguments().getString(ARG_BOOK_CATEGORY)); - BookFilter f = FilterUtil.filterFromCategory(c); - displayList = FilterUtil.applyFilter(bookList, f); - Collections.sort(displayList, BookComparators.getInitialComparator()); - - downloadsAvailable.setAdapter(new BookListAdapter(inflater, displayList)); - setInsets(getActivity(), downloadsAvailable); - } catch (FilterUtil.InvalidFilterCategoryMappingException e) { - // To be honest, there should be no reason you end up here. - Log.e(TAG, e.getMessage()); - } - } - private class DownloadDialogListener implements DialogInterface.OnClickListener { @Override diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/DownloadActivity.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/DownloadActivity.java index b00d505..8041a57 100644 --- a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/DownloadActivity.java +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/DownloadActivity.java @@ -6,6 +6,7 @@ import org.bspeice.minimalbible.activities.BaseNavigationDrawerFragment; import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; import android.os.Bundle; +import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; diff --git a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/manager/RefreshManager.java b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/manager/RefreshManager.java index 9f7aea3..cc794e4 100644 --- a/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/manager/RefreshManager.java +++ b/MinimalBible/src/main/java/org/bspeice/minimalbible/activities/downloader/manager/RefreshManager.java @@ -1,6 +1,7 @@ package org.bspeice.minimalbible.activities.downloader.manager; import android.os.Handler; +import android.os.HandlerThread; import org.bspeice.minimalbible.MinimalBible; import org.crosswire.jsword.book.Book; @@ -17,6 +18,8 @@ import javax.inject.Singleton; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; +import rx.android.schedulers.HandlerThreadScheduler; +import rx.schedulers.Schedulers; /** * Handle refreshing the list of books available as needed @@ -40,20 +43,20 @@ public class RefreshManager { /** * Do the work of kicking off the AsyncTask to refresh books, and make sure we know * when it's done. + * TODO: Should I have a better way of scheduling than Schedulers.io()? */ private void refreshModules() { if (availableModules == null) { - Handler backgroundHandler = new Handler(); availableModules = Observable.from(downloadManager.getInstallers().values()) .map(installer -> { Map> map = new HashMap>(); map.put(installer, installer.getBooks()); return map; - }).observeOn(AndroidSchedulers.handlerThread(backgroundHandler)) + }).subscribeOn(Schedulers.io()) .cache(); // Set refresh complete when it is. - availableModules.subscribeOn(AndroidSchedulers.handlerThread(backgroundHandler)) + availableModules.observeOn(Schedulers.io()) .subscribe((onNext) -> {}, (onError) -> {}, () -> refreshComplete.set(true)); } }