diff --git a/Clover/app/build.gradle b/Clover/app/build.gradle index 48d7e68d..cd0bb4b7 100644 --- a/Clover/app/build.gradle +++ b/Clover/app/build.gradle @@ -99,4 +99,6 @@ dependencies { compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0' compile 'com.squareup.okhttp3:okhttp:3.4.1' compile 'de.greenrobot:eventbus:2.4.0' + compile 'com.google.dagger:dagger:2.2' + annotationProcessor 'com.google.dagger:dagger-compiler:2.2' } diff --git a/Clover/app/src/main/java/org/floens/chan/Chan.java b/Clover/app/src/main/java/org/floens/chan/Chan.java index 6c9d49b6..22121660 100644 --- a/Clover/app/src/main/java/org/floens/chan/Chan.java +++ b/Clover/app/src/main/java/org/floens/chan/Chan.java @@ -27,8 +27,12 @@ import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.Volley; +import org.floens.chan.core.UserAgentProvider; import org.floens.chan.core.cache.FileCache; import org.floens.chan.core.database.DatabaseManager; +import org.floens.chan.core.di.AppModule; +import org.floens.chan.core.di.ChanGraph; +import org.floens.chan.core.di.DaggerChanGraph; import org.floens.chan.core.http.ReplyManager; import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.WatchManager; @@ -41,9 +45,11 @@ import org.floens.chan.utils.Time; import java.io.File; import java.util.Locale; +import javax.inject.Inject; + import de.greenrobot.event.EventBus; -public class Chan extends Application { +public class Chan extends Application implements UserAgentProvider { private static final String TAG = "ChanApplication"; private static final long FILE_CACHE_DISK_SIZE = 50 * 1024 * 1024; @@ -55,15 +61,16 @@ public class Chan extends Application { private static Chan instance; private static RequestQueue volleyRequestQueue; private static ImageLoader imageLoader; - private static BoardManager boardManager; - private static WatchManager watchManager; - private static ReplyManager replyManager; - private static DatabaseManager databaseManager; private static FileCache fileCache; private String userAgent; private int activityForegroundCounter = 0; + protected ChanGraph graph; + + @Inject + DatabaseManager databaseManager; + public Chan() { instance = this; con = this; @@ -82,25 +89,29 @@ public class Chan extends Application { } public static BoardManager getBoardManager() { - return boardManager; + throw new IllegalArgumentException(); } public static WatchManager getWatchManager() { - return watchManager; + throw new IllegalArgumentException(); } public static ReplyManager getReplyManager() { - return replyManager; + throw new IllegalArgumentException(); } public static DatabaseManager getDatabaseManager() { - return databaseManager; + throw new IllegalArgumentException(); } public static FileCache getFileCache() { return fileCache; } + public static ChanGraph getGraph() { + return instance.graph; + } + @Override public void onCreate() { super.onCreate(); @@ -108,13 +119,16 @@ public class Chan extends Application { final long startTime = Time.startTiming(); AndroidUtils.init(); + graph = DaggerChanGraph.builder() + .appModule(new AppModule(this, this)) + .build(); + + graph.inject(this); userAgent = createUserAgent(); File cacheDir = getExternalCacheDir() != null ? getExternalCacheDir() : getCacheDir(); - replyManager = new ReplyManager(this, userAgent); - volleyRequestQueue = Volley.newRequestQueue(this, userAgent, new ProxiedHurlStack(userAgent), new File(cacheDir, Volley.DEFAULT_CACHE_DIR), VOLLEY_CACHE_SIZE); final int runtimeMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); @@ -124,9 +138,9 @@ public class Chan extends Application { fileCache = new FileCache(new File(cacheDir, FILE_CACHE_NAME), FILE_CACHE_DISK_SIZE, getUserAgent()); - databaseManager = new DatabaseManager(this); - boardManager = new BoardManager(databaseManager); - watchManager = new WatchManager(databaseManager); +// sDatabaseManager = new DatabaseManager(this); +// boardManager = new BoardManager(null); +// watchManager = new WatchManager(null); Time.endTiming("Initializing application", startTime); @@ -153,6 +167,7 @@ public class Chan extends Application { } } + @Override public String getUserAgent() { return userAgent; } diff --git a/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java index 336cac59..c4b406e4 100644 --- a/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java @@ -24,7 +24,6 @@ import com.android.volley.Response; import com.android.volley.VolleyError; import org.floens.chan.Chan; -import org.floens.chan.core.database.DatabaseManager; import org.floens.chan.core.exception.ChanLoaderException; import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.Loadable; @@ -51,7 +50,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener listeners = new ArrayList<>(); private final Loadable loadable; private final RequestQueue volleyRequestQueue; - private final DatabaseManager databaseManager; private ChanThread thread; private ChanReaderRequest request; @@ -69,7 +67,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener * Use the async versions when you don't care when the query is done. */ +@Singleton public class DatabaseManager { private static final String TAG = "DatabaseManager"; @@ -70,6 +74,7 @@ public class DatabaseManager { private final DatabaseFilterManager databaseFilterManager; private final DatabaseBoardManager databaseBoardManager; + @Inject public DatabaseManager(Context context) { backgroundExecutor = Executors.newSingleThreadExecutor(); diff --git a/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java b/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java new file mode 100644 index 00000000..f82d5240 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java @@ -0,0 +1,33 @@ +package org.floens.chan.core.di; + +import android.content.Context; + +import org.floens.chan.core.UserAgentProvider; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class AppModule { + private Context applicationContext; + private UserAgentProvider userAgentProvider; + + public AppModule(Context applicationContext, UserAgentProvider userAgentProvider) { + this.applicationContext = applicationContext; + this.userAgentProvider = userAgentProvider; + } + + @Provides + @Singleton + public Context provideApplicationContext() { + return applicationContext; + } + + @Provides + @Singleton + public UserAgentProvider provideUserAgentProvider() { + return userAgentProvider; + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/core/di/ChanGraph.java b/Clover/app/src/main/java/org/floens/chan/core/di/ChanGraph.java new file mode 100644 index 00000000..9d884de7 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/core/di/ChanGraph.java @@ -0,0 +1,33 @@ +package org.floens.chan.core.di; + +import org.floens.chan.Chan; +import org.floens.chan.chan.ChanParser; +import org.floens.chan.core.net.ChanReaderRequest; +import org.floens.chan.core.presenter.ReplyPresenter; +import org.floens.chan.ui.controller.DeveloperSettingsController; +import org.floens.chan.ui.controller.MainSettingsController; +import org.floens.chan.ui.layout.ThreadLayout; + +import javax.inject.Singleton; + +import dagger.Component; + +@Component(modules = { + AppModule.class +}) +@Singleton +public interface ChanGraph { + void inject(Chan chan); + + void inject(MainSettingsController mainSettingsController); + + void inject(ReplyPresenter replyPresenter); + + void inject(ChanReaderRequest chanReaderRequest); + + void inject(ThreadLayout threadLayout); + + void inject(DeveloperSettingsController developerSettingsController); + + ChanParser getChanParser(); +} diff --git a/Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java b/Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java index 08e74935..2cc686e5 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java @@ -19,6 +19,7 @@ package org.floens.chan.core.http; import android.content.Context; +import org.floens.chan.core.UserAgentProvider; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Reply; @@ -27,12 +28,16 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import javax.inject.Singleton; + import okhttp3.OkHttpClient; import okhttp3.Request; /** * To send an reply to 4chan. */ +@Singleton public class ReplyManager { private static final int TIMEOUT = 30000; @@ -42,9 +47,10 @@ public class ReplyManager { private Map drafts = new HashMap<>(); - public ReplyManager(Context context, String userAgent) { + @Inject + public ReplyManager(Context context, UserAgentProvider userAgentProvider) { this.context = context; - this.userAgent = userAgent; + userAgent = userAgentProvider.getUserAgent(); client = new OkHttpClient.Builder() .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/BoardManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/BoardManager.java index a9afda22..07a5accf 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/BoardManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/BoardManager.java @@ -30,8 +30,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; + import de.greenrobot.event.EventBus; +@Singleton public class BoardManager { private static final String TAG = "BoardManager"; @@ -56,6 +60,7 @@ public class BoardManager { private final List savedBoards = new ArrayList<>(); private final Map boardsByCode = new HashMap<>(); + @Inject public BoardManager(DatabaseManager databaseManager) { this.databaseManager = databaseManager; defaultSite = Sites.defaultSite(); diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java index a4283058..b9775d7c 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java @@ -51,6 +51,9 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.inject.Inject; +import javax.inject.Singleton; + import de.greenrobot.event.EventBus; import static org.floens.chan.utils.AndroidUtils.getAppContext; @@ -70,6 +73,7 @@ import static org.floens.chan.utils.AndroidUtils.getAppContext; *

*

All pin adding and removing must go through this class to properly update the watchers. */ +@Singleton public class WatchManager { private static final String TAG = "WatchManager"; @@ -124,6 +128,7 @@ public class WatchManager { private PowerManager.WakeLock wakeLock; private long lastBackgroundUpdateTime; + @Inject public WatchManager(DatabaseManager databaseManager) { alarmManager = (AlarmManager) getAppContext().getSystemService(Context.ALARM_SERVICE); powerManager = (PowerManager) getAppContext().getSystemService(Context.POWER_SERVICE); diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java index f0030168..1ed023d9 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java @@ -21,7 +21,6 @@ import android.text.SpannableString; import android.text.TextUtils; import org.floens.chan.chan.ChanParser; -import org.floens.chan.chan.ChanUrls; import org.floens.chan.core.settings.ChanSettings; import org.jsoup.parser.Parser; @@ -32,6 +31,8 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; +import static org.floens.chan.Chan.getGraph; + /** * Contains all data needed to represent a single post.
* Call {@link #finish()} to parse the comment etc. The post data is invalid if finish returns false.
@@ -175,7 +176,8 @@ public class Post { spoiler = false; } - ChanParser.getInstance().parse(this); + ChanParser chanParser = getGraph().getChanParser(); + chanParser.parse(this); repliesTo = Collections.unmodifiableSet(repliesTo); diff --git a/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java b/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java index 35373511..53e588f8 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java +++ b/Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java @@ -22,7 +22,6 @@ import android.util.JsonReader; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; -import org.floens.chan.Chan; import org.floens.chan.core.database.DatabaseManager; import org.floens.chan.core.database.DatabaseSavedReplyManager; import org.floens.chan.core.manager.FilterEngine; @@ -41,9 +40,11 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import static org.floens.chan.Chan.getGraph; + /** * Process a typical imageboard json response.
- * This class is highly multithreaded, take good care to don't access models that are to be only + * This class is highly multithreaded, take good care to not access models that are to be only * changed on the main thread. */ public class ChanReaderRequest extends JsonReaderRequest { @@ -58,11 +59,12 @@ public class ChanReaderRequest extends JsonReaderRequest cached; private Post op; private FilterEngine filterEngine; - private DatabaseManager databaseManager; private DatabaseSavedReplyManager databaseSavedReplyManager; private List filters; @@ -70,8 +72,10 @@ public class ChanReaderRequest extends JsonReaderRequest listener, ErrorListener errorListener) { super(url, listener, errorListener); + + getGraph().inject(this); + filterEngine = FilterEngine.getInstance(); - databaseManager = Chan.getDatabaseManager(); databaseSavedReplyManager = databaseManager.getDatabaseSavedReplyManager(); } diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java index 3f1e2bda..d9adf1ee 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java @@ -19,7 +19,6 @@ package org.floens.chan.core.presenter; import android.text.TextUtils; -import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; import org.floens.chan.core.database.DatabaseManager; @@ -43,6 +42,9 @@ import java.nio.charset.Charset; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.inject.Inject; + +import static org.floens.chan.Chan.getGraph; import static org.floens.chan.utils.AndroidUtils.getReadableFileSize; import static org.floens.chan.utils.AndroidUtils.getRes; import static org.floens.chan.utils.AndroidUtils.getString; @@ -59,10 +61,17 @@ public class ReplyPresenter implements ReplyManager.HttpCallback, private ReplyPresenterCallback callback; - private ReplyManager replyManager; - private BoardManager boardManager; - private WatchManager watchManager; - private DatabaseManager databaseManager; + @Inject + ReplyManager replyManager; + + @Inject + BoardManager boardManager; + + @Inject + WatchManager watchManager; + + @Inject + DatabaseManager databaseManager; private boolean bound = false; private Loadable loadable; @@ -78,10 +87,7 @@ public class ReplyPresenter implements ReplyManager.HttpCallback, public ReplyPresenter(ReplyPresenterCallback callback) { this.callback = callback; - replyManager = Chan.getReplyManager(); - boardManager = Chan.getBoardManager(); - watchManager = Chan.getWatchManager(); - databaseManager = Chan.getDatabaseManager(); + getGraph().inject(this); } public void bindLoadable(Loadable loadable) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/DeveloperSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/DeveloperSettingsController.java index 28e73564..056c5d17 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/DeveloperSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/DeveloperSettingsController.java @@ -24,7 +24,6 @@ import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; -import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.controller.Controller; import org.floens.chan.core.database.DatabaseManager; @@ -32,13 +31,17 @@ import org.floens.chan.core.model.SavedReply; import java.util.Random; +import javax.inject.Inject; + +import static org.floens.chan.Chan.getGraph; import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.getAttrColor; public class DeveloperSettingsController extends Controller { private TextView summaryText; - private DatabaseManager databaseManager; + @Inject + DatabaseManager databaseManager; public DeveloperSettingsController(Context context) { super(context); @@ -48,7 +51,7 @@ public class DeveloperSettingsController extends Controller { public void onCreate() { super.onCreate(); - databaseManager = Chan.getDatabaseManager(); + getGraph().inject(this); navigationItem.setTitle(R.string.settings_developer); @@ -77,7 +80,7 @@ public class DeveloperSettingsController extends Controller { resetDbButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Chan.getDatabaseManager().reset(); + databaseManager.reset(); System.exit(0); } }); @@ -111,7 +114,7 @@ public class DeveloperSettingsController extends Controller { private void setDbSummary() { String dbSummary = ""; dbSummary += "Database summary:\n"; - dbSummary += Chan.getDatabaseManager().getSummary(); + dbSummary += databaseManager.getSummary(); summaryText.setText(dbSummary); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java index 1b1be17e..61c0ce7d 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java @@ -30,6 +30,7 @@ import android.widget.Toast; import org.floens.chan.Chan; import org.floens.chan.R; +import org.floens.chan.core.database.DatabaseManager; import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.model.Board; import org.floens.chan.core.settings.ChanSettings; @@ -53,8 +54,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.inject.Inject; + import de.greenrobot.event.EventBus; +import static org.floens.chan.Chan.getGraph; import static org.floens.chan.ui.theme.ThemeHelper.theme; import static org.floens.chan.utils.AndroidUtils.getString; @@ -80,6 +84,9 @@ public class MainSettingsController extends SettingsController implements Toolba private PopupWindow advancedSettingsHint; + @Inject + DatabaseManager databaseManager; + public MainSettingsController(Context context) { super(context); } @@ -88,6 +95,7 @@ public class MainSettingsController extends SettingsController implements Toolba public void onCreate() { super.onCreate(); + getGraph().inject(this); EventBus.getDefault().register(this); navigationItem.setTitle(R.string.settings_screen); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java index 2be54801..081e59a5 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java @@ -37,7 +37,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.floens.chan.R; -import org.floens.chan.chan.ChanParser; import org.floens.chan.controller.Controller; import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Loadable; @@ -61,6 +60,7 @@ import org.floens.chan.utils.Time; import java.util.ArrayList; import java.util.List; +import static org.floens.chan.Chan.getGraph; import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.getAttrColor; import static org.floens.chan.utils.AndroidUtils.getString; @@ -251,7 +251,7 @@ public class ThemeSettingsController extends Controller implements View.OnClickL "http://example.com/" + "
" + "Phasellus consequat semper sodales. Donec dolor lectus, aliquet nec mollis vel, rutrum vel enim."; - ChanParser.getInstance().parse(theme, post); + getGraph().getChanParser().parse(theme, post); LinearLayout linearLayout = new LinearLayout(themeContext); linearLayout.setOrientation(LinearLayout.VERTICAL); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java index 4f6ccea4..9365b1d2 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java @@ -40,7 +40,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; -import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.controller.Controller; import org.floens.chan.core.database.DatabaseManager; @@ -63,6 +62,9 @@ import org.floens.chan.utils.AndroidUtils; import java.util.List; +import javax.inject.Inject; + +import static org.floens.chan.Chan.getGraph; import static org.floens.chan.ui.theme.ThemeHelper.theme; import static org.floens.chan.utils.AndroidUtils.fixSnackbarText; import static org.floens.chan.utils.AndroidUtils.getString; @@ -77,7 +79,8 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T ERROR; } - private DatabaseManager databaseManager; + @Inject + DatabaseManager databaseManager; private ThreadLayoutCallback callback; @@ -528,7 +531,7 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T } private void init() { - databaseManager = Chan.getDatabaseManager(); + getGraph().inject(this); } @Override diff --git a/Clover/build.gradle b/Clover/build.gradle index e7e3c60b..2e369803 100644 --- a/Clover/build.gradle +++ b/Clover/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.android.tools.build:gradle:2.2.3' } }