Upgrade to Dagger 2

Still some pressing issues, but the hard work is done.
This commit is contained in:
Bradlee Speice
2015-06-28 21:35:55 -04:00
parent ae499803fb
commit 717582fccc
27 changed files with 430 additions and 539 deletions

View File

@ -10,14 +10,11 @@ import org.crosswire.jsword.book.sword.SwordBookPath;
import java.io.File;
import dagger.ObjectGraph;
/**
* Set up the application!
*/
public class MinimalBible extends Application implements Injector {
public class MinimalBible extends Application {
private static Context mContext;
private ObjectGraph mObjectGraph;
public static MinimalBible get(Context ctx) {
return (MinimalBible) ctx.getApplicationContext();
@ -33,22 +30,9 @@ public class MinimalBible extends Application implements Injector {
super.onCreate();
mContext = this;
Logger.init().setLogLevel(LogLevel.NONE);
buildObjGraph();
setJswordHome();
}
public void buildObjGraph() {
mObjectGraph = ObjectGraph.create(Modules.list(this));
}
public void inject(Object o) {
mObjectGraph.inject(o);
}
public ObjectGraph plus(Object... modules) {
return mObjectGraph.plus(modules);
}
/**
* Notify jSword that it needs to store files in the Android internal directory
* NOTE: Android will uninstall these files if you uninstall MinimalBible.

View File

@ -16,9 +16,6 @@ import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import de.devland.esperandro.Esperandro;
@ -29,8 +26,7 @@ import rx.functions.Func1;
/**
* Entry point for the default modules used by MinimalBible
*/
@SuppressWarnings("unused")
@Module(library = true)
@Module
public class MinimalBibleModules {
MinimalBible app;
@ -39,7 +35,6 @@ public class MinimalBibleModules {
}
@Provides
@Singleton
Application provideApplication() {
return app;
}
@ -51,7 +46,6 @@ public class MinimalBibleModules {
* @return the list of books (by name) to ignore
*/
@Provides
@Singleton
List<String> invalidBooks() {
List<String> list = new ArrayList<>();
list.add("ABU"); // Missing content
@ -61,30 +55,15 @@ public class MinimalBibleModules {
return list;
}
//TODO: Move this to a true async
/**
* Provide a raw reference to the books installed. Please don't use this, chances are
* you should go through List<Book> since it excludes the invalid books.
*
* @return The raw reference to JSword Books class
*/
@Provides
@Singleton
Books provideInstalledBooks() {
return Books.installed();
}
/**
* Use this to get the list of books installed, as filtered by what should be excluded
*
* @param b The raw Books instance to get the installed list from
* @param invalidBooks The books to exclude from usage
* @return The books available for using
*/
@Provides
List<Book> provideInstalledBooks(Books b, final List<String> invalidBooks) {
List<Book> rawBooks = b.getBooks();
List<Book> provideInstalledBooks(final List<String> invalidBooks) {
List<Book> rawBooks = Books.installed().getBooks();
return Observable.from(rawBooks)
.filter(new Func1<Book, Boolean>() {
@Override
@ -96,14 +75,18 @@ public class MinimalBibleModules {
}
@Provides
@Singleton
BibleViewerPreferences providePrefs() {
return Esperandro.getPreferences(BibleViewerPreferences.class, app);
}
/**
* TODO: Assume a book exists, throw an error if nothing available
*
* @param bookManager
* @param prefs
* @return
*/
@Provides
@Singleton
@Named("MainBook")
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
final AtomicReference<Book> mBook = new AtomicReference<>(null);
bookManager.getInstalledBooks()
@ -151,13 +134,11 @@ public class MinimalBibleModules {
}
@Provides
@Singleton
BookManager bookManager(List<String> exclude) {
return new BookManager(exclude);
}
@Provides
@Singleton
IndexManager indexManager() {
return IndexManagerFactory.getIndexManager();
}

View File

@ -5,8 +5,6 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import dagger.ObjectGraph;
/**
* Holding location for activity object graphs.
* This technique could be extended to other things, but honestly,
@ -14,10 +12,10 @@ import dagger.ObjectGraph;
* an ObjectGraph anyway.
* This works because getSupportFragmentManager() is scoped to each activity.
*/
public class OGHolder extends Fragment {
public class OGHolder<T> extends Fragment {
private final static String TAG = "OGHolder";
private ObjectGraph mObjectGraph;
private T mComponent;
public static OGHolder get(FragmentActivity activity) {
FragmentManager manager = activity.getSupportFragmentManager();
@ -35,11 +33,11 @@ public class OGHolder extends Fragment {
setRetainInstance(true);
}
public void persistGraph(ObjectGraph graph) {
mObjectGraph = graph;
public T getmComponent() {
return mComponent;
}
public ObjectGraph fetchGraph() {
return mObjectGraph;
public void setmComponent(T mComponent) {
this.mComponent = mComponent;
}
}

View File

@ -64,6 +64,11 @@ public class BookItemHolder {
public void bindHolder() {
acronym.setText(b.getInitials());
itemName.setText(b.getName());
// TODO: I shouldn't have to check for this condition.
if (bookManager == null) {
displayInstalled();
return;
}
DLProgressEvent dlProgressEvent = bookManager.getDownloadProgress(b);
if (dlProgressEvent != null) {
displayProgress(dlProgressEvent);

View File

@ -13,9 +13,11 @@ import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseFragment;
import org.bspeice.minimalbible.activity.downloader.injection.ActivityContextModule;
import org.bspeice.minimalbible.activity.downloader.injection.BookListFragmentComponent;
import org.bspeice.minimalbible.activity.downloader.injection.DaggerBookListFragmentComponent;
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.crosswire.common.util.Language;
@ -69,8 +71,12 @@ public class BookListFragment extends BaseFragment {
* Returns a new instance of this fragment for the given section number.
* TODO: Switch to AutoFactory/@Provides rather than inline creation.
*/
public static BookListFragment newInstance(BookCategory c) {
public static BookListFragment newInstance(BookCategory c, DownloadActivity activity) {
BookListFragment fragment = new BookListFragment();
DaggerBookListFragmentComponent.builder()
.activityContextModule(new ActivityContextModule(activity))
.build()
.injectBookListFragment(fragment);
Bundle args = new Bundle();
args.putString(ARG_BOOK_CATEGORY, c.toString());
fragment.setArguments(args);
@ -80,7 +86,10 @@ public class BookListFragment extends BaseFragment {
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
((Injector)getActivity()).inject(this);
BookListFragmentComponent component = DaggerBookListFragmentComponent.builder()
.activityContextModule(new ActivityContextModule((DownloadActivity) getActivity()))
.build();
component.injectBookListFragment(this);
bookCategory = BookCategory.fromString(getArguments().getString(ARG_BOOK_CATEGORY));
availableLanguages = localeManager.sortedLanguagesForCategory(bookCategory);

View File

@ -15,10 +15,10 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
import org.bspeice.minimalbible.activity.downloader.injection.DaggerDownloadActivityComponent;
import org.bspeice.minimalbible.activity.downloader.injection.DownloadActivityComponent;
import org.bspeice.minimalbible.activity.settings.MinimalBibleSettings;
import org.crosswire.jsword.book.BookCategory;
import org.jetbrains.annotations.NotNull;
@ -26,18 +26,15 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.ButterKnife;
import butterknife.InjectView;
import dagger.ObjectGraph;
public class DownloadActivity extends BaseActivity implements
Injector,
AdapterView.OnItemClickListener {
@Inject
@Named("ValidCategories")
List<BookCategory> validCategories;
@InjectView(R.id.navigation_drawer)
@ -52,30 +49,10 @@ public class DownloadActivity extends BaseActivity implements
@InjectView(R.id.drawer_layout)
DrawerLayout drawerLayout;
private ObjectGraph daObjectGraph;
/**
* Build a scoped object graph for anything used by the DownloadActivity
*/
private void buildObjGraph() {
if (daObjectGraph == null) {
OGHolder holder = OGHolder.get(this);
ObjectGraph holderGraph = holder.fetchGraph();
if (holderGraph == null) {
daObjectGraph = MinimalBible.get(this)
.plus(new DownloadActivityModules(this));
holder.persistGraph(daObjectGraph);
} else {
daObjectGraph = holderGraph;
}
}
daObjectGraph.inject(this);
}
@Override
public void inject(Object o) {
buildObjGraph();
daObjectGraph.inject(o);
// TODO: Cache the component
DownloadActivityComponent component = DaggerDownloadActivityComponent.create();
component.injectDownloadActivity(this);
}
@Override
@ -138,7 +115,7 @@ public class DownloadActivity extends BaseActivity implements
fragmentManager
.beginTransaction()
.replace(R.id.content,
BookListFragment.newInstance(validCategories.get(position)))
BookListFragment.newInstance(validCategories.get(position), this))
.commit();
drawerLayout.closeDrawers();

View File

@ -1,130 +0,0 @@
package org.bspeice.minimalbible.activity.downloader;
import android.content.Context;
import android.net.ConnectivityManager;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBibleModules;
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.bspeice.minimalbible.activity.search.MBIndexManager;
import org.crosswire.jsword.book.BookCategory;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.install.InstallManager;
import org.crosswire.jsword.book.install.Installer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import de.devland.esperandro.Esperandro;
import rx.subjects.PublishSubject;
/**
* Module mappings for the classes under the Download Activity
*/
@Module(
injects = {
BookListFragment.class,
BookItemHolder.class,
BookManager.class,
RefreshManager.class,
DownloadActivity.class
},
addsTo = MinimalBibleModules.class,
library = true
)
@SuppressWarnings("unused")
public class DownloadActivityModules {
DownloadActivity activity;
DownloadActivityModules(DownloadActivity activity) {
this.activity = activity;
}
@Provides
@Singleton
DownloadPrefs provideDownloadPrefs() {
return Esperandro.getPreferences(DownloadPrefs.class, activity);
}
@Provides
@Singleton
DownloadActivity provideDownloadActivity() {
return activity;
}
@Provides
@Singleton
Injector provideActivityInjector() {
return activity;
}
/**
* Provide the context for the DownloadActivity. We name it so that we don't have to
* \@Provides a specific class, but can keep track of what exactly we mean by "Context"
*
* @return The DownloadActivity Context
*/
@Provides
@Singleton
@Named("DownloadActivityContext")
Context provideActivityContext() {
return activity;
}
@Provides
@Singleton
PublishSubject<DLProgressEvent> dlProgressEventPublisher() {
return PublishSubject.create();
}
@Provides
@Singleton
BookManager provideBookDownloadManager(Books installedBooks, RefreshManager rm,
PublishSubject<DLProgressEvent> progressEvents,
MBIndexManager mbIndexManager) {
return new BookManager(installedBooks, rm, progressEvents, mbIndexManager);
}
@Provides
@Singleton
@Named("ValidCategories")
List<BookCategory> provideValidCategories() {
return new ArrayList<BookCategory>() {{
add(BookCategory.BIBLE);
add(BookCategory.COMMENTARY);
add(BookCategory.DICTIONARY);
add(BookCategory.MAPS);
}};
}
@Provides
@Singleton
Collection<Installer> provideInstallers() {
return new InstallManager().getInstallers().values();
}
@Provides
@Singleton
RefreshManager provideRefreshManager(Collection<Installer> installers, List<String> exclude,
DownloadPrefs prefs,
@Named("DownloadActivityContext") Context context) {
return new RefreshManager(installers, exclude, prefs,
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
}
@Provides
LocaleManager provideLocaleManager(RefreshManager refreshManager) {
return new LocaleManager(refreshManager);
}
}

View File

@ -0,0 +1,21 @@
package org.bspeice.minimalbible.activity.downloader.injection;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import dagger.Module;
import dagger.Provides;
@Module
public class ActivityContextModule {
DownloadActivity activity;
public ActivityContextModule(DownloadActivity activity) {
this.activity = activity;
}
@Provides
DownloadActivity downloadActivity() {
return activity;
}
}

View File

@ -0,0 +1,13 @@
package org.bspeice.minimalbible.activity.downloader.injection;
import org.bspeice.minimalbible.activity.downloader.BookListFragment;
import org.bspeice.minimalbible.common.injection.InvalidBookModule;
import dagger.Component;
@Component(modules = {ActivityContextModule.class, DownloadManagerModule.class,
InvalidBookModule.class})
public interface BookListFragmentComponent {
BookListFragment injectBookListFragment(BookListFragment fragment);
}

View File

@ -0,0 +1,11 @@
package org.bspeice.minimalbible.activity.downloader.injection;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import dagger.Component;
@Component(modules = ValidCategoryModule.class)
public interface DownloadActivityComponent {
public DownloadActivity injectDownloadActivity(DownloadActivity activity);
}

View File

@ -0,0 +1,62 @@
package org.bspeice.minimalbible.activity.downloader.injection;
import android.content.Context;
import android.net.ConnectivityManager;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.bspeice.minimalbible.activity.search.MBIndexManager;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.install.InstallManager;
import org.crosswire.jsword.book.install.Installer;
import java.util.Collection;
import java.util.List;
import dagger.Module;
import dagger.Provides;
import de.devland.esperandro.Esperandro;
import rx.subjects.PublishSubject;
@Module
public class DownloadManagerModule {
@Provides
DownloadPrefs provideDownloadPrefs(DownloadActivity activity) {
return Esperandro.getPreferences(DownloadPrefs.class, activity);
}
@Provides
PublishSubject<DLProgressEvent> dlProgressEventPublisher() {
return PublishSubject.create();
}
@Provides
BookManager provideBookDownloadManager(Books installedBooks, RefreshManager rm,
PublishSubject<DLProgressEvent> progressEvents,
MBIndexManager mbIndexManager) {
return new BookManager(installedBooks, rm, progressEvents, mbIndexManager);
}
@Provides
Collection<Installer> provideInstallers() {
return new InstallManager().getInstallers().values();
}
@Provides
RefreshManager provideRefreshManager(Collection<Installer> installers, List<String> exclude,
DownloadPrefs prefs,
DownloadActivity activity) {
return new RefreshManager(installers, exclude, prefs,
(ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE));
}
@Provides
LocaleManager provideLocaleManager(RefreshManager refreshManager) {
return new LocaleManager(refreshManager);
}
}

View File

@ -0,0 +1,23 @@
package org.bspeice.minimalbible.activity.downloader.injection;
import org.crosswire.jsword.book.BookCategory;
import java.util.ArrayList;
import java.util.List;
import dagger.Module;
import dagger.Provides;
@Module
public class ValidCategoryModule {
@Provides
List<BookCategory> provideValidCategories() {
return new ArrayList<BookCategory>() {{
add(BookCategory.BIBLE);
add(BookCategory.COMMENTARY);
add(BookCategory.DICTIONARY);
add(BookCategory.MAPS);
}};
}
}

View File

@ -5,11 +5,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
import org.bspeice.minimalbible.common.injection.MainBookModule;
import org.crosswire.jsword.passage.Verse;
import java.util.List;
@ -18,11 +16,9 @@ import javax.inject.Inject;
import butterknife.ButterKnife;
import butterknife.InjectView;
import dagger.ObjectGraph;
public class BasicSearch extends BaseActivity
implements Injector {
public class BasicSearch extends BaseActivity {
@Inject
SearchProvider searchProvider;
@ -33,25 +29,13 @@ public class BasicSearch extends BaseActivity
@InjectView(R.id.toolbar)
Toolbar toolbar;
private ObjectGraph searchObjGraph;
private void buildObjGraph() {
if (searchObjGraph == null) {
OGHolder holder = OGHolder.get(this);
searchObjGraph = holder.fetchGraph();
if (searchObjGraph == null) {
searchObjGraph = MinimalBible.get(this)
.plus(new SearchModules());
holder.persistGraph(searchObjGraph);
}
}
searchObjGraph.inject(this);
}
@Override
public void inject(Object o) {
buildObjGraph();
searchObjGraph.inject(o);
public void inject() {
// TODO: Cache the component
BasicSearchComponent component = DaggerBasicSearchComponent.builder()
.mainBookModule(new MainBookModule(this))
.build();
component.injectBasicSearch(this);
}
@Override
@ -59,7 +43,7 @@ public class BasicSearch extends BaseActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
inject(this);
inject();
ButterKnife.inject(this);
setSupportActionBar(toolbar);

View File

@ -0,0 +1,12 @@
package org.bspeice.minimalbible.activity.search;
import org.bspeice.minimalbible.common.injection.InvalidBookModule;
import org.bspeice.minimalbible.common.injection.MainBookModule;
import dagger.Component;
@Component(modules = {SearchModules.class, MainBookModule.class, InvalidBookModule.class})
public interface BasicSearchComponent {
BasicSearch injectBasicSearch(BasicSearch basicSearch);
}

View File

@ -1,25 +1,19 @@
package org.bspeice.minimalbible.activity.search;
import org.bspeice.minimalbible.MinimalBibleModules;
import android.support.annotation.Nullable;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.index.IndexManager;
import javax.inject.Named;
import dagger.Module;
import dagger.Provides;
@Module(
injects = BasicSearch.class,
addsTo = MinimalBibleModules.class
)
@Module
public class SearchModules {
@Provides
SearchProvider searchProvider(@Named("MainBook") Book book,
SearchProvider searchProvider(@Nullable Book book,
IndexManager indexManager) {
return new SearchProvider(indexManager, book);
}
}

View File

@ -5,24 +5,14 @@ import android.preference.PreferenceActivity;
import android.support.v7.widget.Toolbar;
import android.widget.LinearLayout;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.MinimalBibleModules;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
import butterknife.ButterKnife;
import butterknife.InjectView;
import dagger.Module;
import dagger.ObjectGraph;
/**
* Created by bspeice on 12/29/14.
*/
public class MinimalBibleSettings extends PreferenceActivity
implements Injector {
public class MinimalBibleSettings extends PreferenceActivity {
ObjectGraph settingsGraph;
@InjectView(R.id.toolbar)
Toolbar toolbar;
@InjectView(R.id.container)
@ -41,24 +31,4 @@ public class MinimalBibleSettings extends PreferenceActivity
toolbar.setTitle(R.string.action_settings);
BaseActivity.setupInsets(this, root);
}
private ObjectGraph buildObjGraph() {
MinimalBible app = (MinimalBible) getApplicationContext();
return app.plus(new SettingsModule());
}
@Override
public void inject(Object o) {
if (settingsGraph == null) {
settingsGraph = buildObjGraph();
}
settingsGraph.inject(o);
}
@Module(injects = AvailableBookPreference.class,
addsTo = MinimalBibleModules.class)
class SettingsModule {
}
}

View File

@ -5,6 +5,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
@ -13,32 +14,31 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import org.bspeice.minimalbible.activity.search.BasicSearch;
import org.bspeice.minimalbible.activity.search.MBIndexManager;
import org.bspeice.minimalbible.activity.settings.MinimalBibleSettings;
import org.bspeice.minimalbible.activity.viewer.injection.BibleViewerModules;
import org.bspeice.minimalbible.activity.viewer.injection.DaggerViewerComponent;
import org.bspeice.minimalbible.activity.viewer.injection.ViewerComponent;
import org.bspeice.minimalbible.common.injection.MainBookModule;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.index.IndexStatus;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.ButterKnife;
import butterknife.InjectView;
import dagger.ObjectGraph;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.subjects.PublishSubject;
public class BibleViewer extends BaseActivity implements Injector {
public class BibleViewer extends BaseActivity {
@Inject
@Named("MainBook")
@Nullable
Book mainBook;
@Inject
@ -62,30 +62,14 @@ public class BibleViewer extends BaseActivity implements Injector {
@InjectView(R.id.drawer_layout)
DrawerLayout drawerLayout;
private ObjectGraph bvObjectGraph;
/**
* Build a scoped object graph for anything used by the BibleViewer
* and inject ourselves
* TODO: Refactor so buildObjGraph doesn't have side effects
*/
private void buildObjGraph() {
if (bvObjectGraph == null) {
OGHolder holder = OGHolder.get(this);
bvObjectGraph = holder.fetchGraph();
if (bvObjectGraph == null) {
bvObjectGraph = MinimalBible.get(this)
.plus(new BibleViewerModules(this));
holder.persistGraph(bvObjectGraph);
}
}
bvObjectGraph.inject(this);
}
@Override
public void inject(Object o) {
buildObjGraph();
bvObjectGraph.inject(o);
public void inject() {
// TODO: Cache the component
// TODO: Refactor the component design
ViewerComponent component = DaggerViewerComponent.builder()
.mainBookModule(new MainBookModule(this))
.bibleViewerModules(new BibleViewerModules(this))
.build();
component.injectBibleViewer(this);
}
/**
@ -96,7 +80,7 @@ public class BibleViewer extends BaseActivity implements Injector {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.inject(this);
this.inject();
// Check that we have a book installed
if (mainBook == null) {

View File

@ -1,8 +1,7 @@
package org.bspeice.minimalbible.activity.viewer;
package org.bspeice.minimalbible.activity.viewer.injection;
import org.bspeice.minimalbible.MinimalBibleModules;
import javax.inject.Singleton;
import org.bspeice.minimalbible.activity.viewer.BibleViewer;
import org.bspeice.minimalbible.activity.viewer.BookScrollEvent;
import dagger.Module;
import dagger.Provides;
@ -11,13 +10,7 @@ import rx.subjects.PublishSubject;
/**
* Modules used for the BibleViewer activity
*/
@Module(
injects = {
BibleViewer.class,
},
addsTo = MinimalBibleModules.class
)
@SuppressWarnings("unused")
@Module
public class BibleViewerModules {
BibleViewer activity;
@ -27,7 +20,6 @@ public class BibleViewerModules {
@Provides
@Singleton
PublishSubject<BookScrollEvent> scrollEventPublisher() {
return PublishSubject.create();
}

View File

@ -0,0 +1,14 @@
package org.bspeice.minimalbible.activity.viewer.injection;
import org.bspeice.minimalbible.activity.viewer.BibleViewer;
import org.bspeice.minimalbible.common.injection.InvalidBookModule;
import org.bspeice.minimalbible.common.injection.MainBookModule;
import dagger.Component;
@Component(modules = {MainBookModule.class, BibleViewerModules.class,
InvalidBookModule.class})
public interface ViewerComponent {
public BibleViewer injectBibleViewer(BibleViewer viewer);
}

View File

@ -0,0 +1,26 @@
package org.bspeice.minimalbible.common.injection;
import java.util.ArrayList;
import java.util.List;
import dagger.Module;
import dagger.Provides;
@Module
public class InvalidBookModule {
/**
* Provide a list of book names that are known bad. This can be because they trigger NPE,
* or are just missing lots of content, etc.
*
* @return the list of books (by name) to ignore
*/
@Provides
List<String> invalidBooks() {
List<String> list = new ArrayList<>();
list.add("ABU"); // Missing content
list.add("ERen_no"); // Thinks its installed, when it isn't. Triggers NPE
list.add("ot1nt2"); // Thinks its installed, when it isn't. Triggers NPE
return list;
}
}

View File

@ -0,0 +1,124 @@
package org.bspeice.minimalbible.common.injection;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.Log;
import org.bspeice.minimalbible.activity.search.MBIndexManager;
import org.bspeice.minimalbible.activity.viewer.BibleViewerPreferences;
import org.bspeice.minimalbible.service.manager.BookManager;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.index.IndexManager;
import org.crosswire.jsword.index.IndexManagerFactory;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference;
import dagger.Module;
import dagger.Provides;
import de.devland.esperandro.Esperandro;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
@Module
public class MainBookModule {
private Context context;
public MainBookModule(Context context) {
this.context = context;
}
/**
* Use this to get the list of books installed, as filtered by what should be excluded
*
* @param b The raw Books instance to get the installed list from
* @param invalidBooks The books to exclude from usage
* @return The books available for using
*/
@Provides
List<Book> provideInstalledBooks(Books b, final List<String> invalidBooks) {
List<Book> rawBooks = b.getBooks();
return Observable.from(rawBooks)
.filter(new Func1<Book, Boolean>() {
@Override
public Boolean call(Book book) {
return !invalidBooks.contains(book.getInitials());
}
})
.toList().toBlocking().first();
}
// TODO: Preferences to a separate module?
@Provides
BibleViewerPreferences providePrefs() {
return Esperandro.getPreferences(BibleViewerPreferences.class, context);
}
@Provides
@Nullable
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
final AtomicReference<Book> mBook = new AtomicReference<>(null);
bookManager.getInstalledBooks()
.first(new Func1<Book, Boolean>() {
@Override
public Boolean call(Book book) {
return book.getInitials().equals(prefs.defaultBookInitials());
}
})
.subscribe(new Action1<Book>() {
@Override
public void call(Book book) {
mBook.set(book);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Log.d("BibleViewerModules", throwable.getLocalizedMessage());
}
});
if (mBook.get() == null) {
try {
Book fallback;
fallback = bookManager.getInstalledBooks()
.onErrorReturn(new Func1<Throwable, Book>() {
@Override
public Book call(Throwable throwable) {
// If there's no book installed, we can't select the main one...
return null;
}
})
.toBlocking().first();
prefs.defaultBookInitials(fallback.getName());
mBook.set(fallback);
} catch (NoSuchElementException e) {
// If no books are installed, there's really nothing we can do...
Log.d("BibleViewerModules", "No books are installed, so can't select a main book.");
return null;
}
}
return mBook.get();
}
@Provides
BookManager bookManager(List<String> exclude) {
return new BookManager(exclude);
}
@Provides
IndexManager indexManager() {
return IndexManagerFactory.getIndexManager();
}
@Provides
MBIndexManager mbIndexManager(IndexManager indexManager) {
return new MBIndexManager(indexManager);
}
}

View File

@ -1,5 +1,6 @@
package org.bspeice.minimalbible.activity.downloader.manager
import android.util.Log
import org.crosswire.common.util.Language
import org.crosswire.jsword.book.BookCategory
import rx.Observable
@ -33,6 +34,7 @@ class LocaleManager(val rM: RefreshManager) {
fun sortedLanguagesForCategory(cat: BookCategory): List<Language> =
languagesForCategory(cat)
.doOnNext { Log.d("LocaleManager", "Just trying to do something... ${it}") }
// Finally, sort all languages, prioritizing the current
.toSortedList { left, right -> compareLanguages(left, right, currentLanguage) }
// And flatten this into the actual List needed

View File

@ -1,6 +1,7 @@
package org.bspeice.minimalbible.activity.downloader.manager
import android.net.ConnectivityManager
import android.util.Log
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs
import org.crosswire.jsword.book.Book
import org.crosswire.jsword.book.install.Installer
@ -16,21 +17,24 @@ class RefreshManager(val installers: Collection<Installer>,
val currentTime = Calendar.getInstance().getTime().getTime()
val fifteenDaysAgo = currentTime - 1296000
val availableModules: Observable<Map<Installer, List<Book>>> =
Observable.from(installers)
.map {
if (performReload())
it.reloadBookList()
val availableModules: Observable<Map<Installer, List<Book>>> = Observable.from(installers)
.map {
/*
if (performReload())
it.reloadBookList()
*/
Log.d("RefreshManager", "Just trying to do something...")
// TODO: mapOf(it to booksFromInstaller)
mapOf(Pair(it,
booksFromInstaller(it, exclude)))
}
// Don't update timestamps until done. Additionally, make this operation
// part of the pipeline, so it remains a cold observable
.doOnCompleted { prefs.downloadRefreshedOn(currentTime) }
.subscribeOn(Schedulers.io())
.cache()
// TODO: mapOf(it to booksFromInstaller)
mapOf(Pair(it,
booksFromInstaller(it, exclude)))
}
// Don't update timestamps until done. Additionally, make this operation
// part of the pipeline, so it remains a cold observable
.doOnCompleted { prefs.downloadRefreshedOn(currentTime) }
.subscribeOn(Schedulers.io())
.doOnError({ Log.e("RefreshManager", "Testing", it) })
.cache()
val flatModules: Observable<Book> =
availableModules
@ -53,8 +57,10 @@ class RefreshManager(val installers: Collection<Installer>,
prefs.downloadRefreshedOn(),
connManager?.getActiveNetworkInfo()?.getType())
fun booksFromInstaller(inst: Installer, exclude: List<String>) =
inst.getBooks().filterNot { exclude contains it.getInitials() }
fun booksFromInstaller(inst: Installer, exclude: List<String>): List<Book> {
Log.d("Getting books from: ", "${inst.getInstallerDefinition()}")
return inst.getBooks().filterNot { exclude contains it.getInitials() }
}
fun installerFromBook(b: Book): Observable<Installer> = Observable.just(
availableModules.filter {