From 77465c83dd8e24f6de8a2f4cd0e77239d98c8a85 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Thu, 4 Feb 2016 23:59:01 -0500 Subject: [PATCH] Reactive code for reading activity --- .../lightning/activity/BrowserActivity.java | 4 +- .../lightning/activity/IncognitoActivity.java | 6 +- .../lightning/activity/MainActivity.java | 6 +- .../lightning/activity/ReadingActivity.java | 138 +++++++++------- .../lightning/activity/TabsManager.java | 20 +-- .../acr/browser/lightning/react/Action.java | 10 +- .../browser/lightning/react/Observable.java | 147 ++++++++++-------- .../browser/lightning/react/OnSubscribe.java | 59 +++++++ .../browser/lightning/react/Subscriber.java | 16 +- .../browser/lightning/react/Subscription.java | 44 +----- .../browser/lightning/view/LightningView.java | 14 +- 11 files changed, 269 insertions(+), 195 deletions(-) create mode 100644 app/src/main/java/acr/browser/lightning/react/OnSubscribe.java diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index b0284bd..1809a90 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -111,7 +111,7 @@ import acr.browser.lightning.fragment.BookmarksFragment; import acr.browser.lightning.fragment.TabsFragment; import acr.browser.lightning.object.SearchAdapter; import acr.browser.lightning.react.Schedulers; -import acr.browser.lightning.react.Subscription; +import acr.browser.lightning.react.Subscriber; import acr.browser.lightning.receiver.NetworkReceiver; import com.anthonycr.grant.PermissionsManager; @@ -360,7 +360,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } mTabsManager.initializeTabs(this, getIntent(), isIncognito()) - .subscribe(new Subscription() { + .subscribe(new Subscriber() { @Override public void onNext(Void item) {} diff --git a/app/src/main/java/acr/browser/lightning/activity/IncognitoActivity.java b/app/src/main/java/acr/browser/lightning/activity/IncognitoActivity.java index e05512d..075237c 100644 --- a/app/src/main/java/acr/browser/lightning/activity/IncognitoActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/IncognitoActivity.java @@ -11,7 +11,7 @@ import android.webkit.CookieSyncManager; import acr.browser.lightning.R; import acr.browser.lightning.react.Action; import acr.browser.lightning.react.Observable; -import acr.browser.lightning.react.Subscriber; +import acr.browser.lightning.react.OnSubscribe; @SuppressWarnings("deprecation") public class IncognitoActivity extends BrowserActivity { @@ -20,13 +20,13 @@ public class IncognitoActivity extends BrowserActivity { public Observable updateCookiePreference() { return Observable.create(new Action() { @Override - public void onSubscribe(@NonNull Subscriber subscriber) { + public void onSubscribe(@NonNull OnSubscribe onSubscribe) { CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { CookieSyncManager.createInstance(IncognitoActivity.this); } cookieManager.setAcceptCookie(mPreferences.getIncognitoCookiesEnabled()); - subscriber.onComplete(); + onSubscribe.onComplete(); } }); } diff --git a/app/src/main/java/acr/browser/lightning/activity/MainActivity.java b/app/src/main/java/acr/browser/lightning/activity/MainActivity.java index e0eeb79..a011161 100644 --- a/app/src/main/java/acr/browser/lightning/activity/MainActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/MainActivity.java @@ -11,7 +11,7 @@ import android.webkit.CookieSyncManager; import acr.browser.lightning.R; import acr.browser.lightning.react.Action; import acr.browser.lightning.react.Observable; -import acr.browser.lightning.react.Subscriber; +import acr.browser.lightning.react.OnSubscribe; @SuppressWarnings("deprecation") public class MainActivity extends BrowserActivity { @@ -20,13 +20,13 @@ public class MainActivity extends BrowserActivity { public Observable updateCookiePreference() { return Observable.create(new Action() { @Override - public void onSubscribe(@NonNull Subscriber subscriber) { + public void onSubscribe(@NonNull OnSubscribe onSubscribe) { CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { CookieSyncManager.createInstance(MainActivity.this); } cookieManager.setAcceptCookie(mPreferences.getCookiesEnabled()); - subscriber.onComplete(); + onSubscribe.onComplete(); } }); } diff --git a/app/src/main/java/acr/browser/lightning/activity/ReadingActivity.java b/app/src/main/java/acr/browser/lightning/activity/ReadingActivity.java index 13be27d..ba8ba08 100644 --- a/app/src/main/java/acr/browser/lightning/activity/ReadingActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/ReadingActivity.java @@ -10,6 +10,8 @@ import android.graphics.PorterDuff; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -29,6 +31,12 @@ import acr.browser.lightning.R; import acr.browser.lightning.app.BrowserApp; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.preference.PreferenceManager; +import acr.browser.lightning.react.Action; +import acr.browser.lightning.react.Observable; +import acr.browser.lightning.react.OnSubscribe; +import acr.browser.lightning.react.Schedulers; +import acr.browser.lightning.react.Subscriber; +import acr.browser.lightning.react.Subscription; import acr.browser.lightning.reading.HtmlFetcher; import acr.browser.lightning.reading.JResult; import acr.browser.lightning.utils.ThemeUtils; @@ -50,7 +58,7 @@ public class ReadingActivity extends AppCompatActivity { private String mUrl = null; private int mTextSize; private ProgressDialog mProgressDialog; - private PageLoader mLoaderReference; + private Subscription mPageLoaderSubscription; private static final float XXLARGE = 30.0f; private static final float XLARGE = 26.0f; @@ -141,70 +149,87 @@ public class ReadingActivity extends AppCompatActivity { } if (getSupportActionBar() != null) getSupportActionBar().setTitle(Utils.getDomainName(mUrl)); - mLoaderReference = new PageLoader(this); - mLoaderReference.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mUrl); - return true; - } + mPageLoaderSubscription = loadPage(mUrl).subscribeOn(Schedulers.worker()) + .observeOn(Schedulers.main()) + .subscribe(new Subscriber() { + @Override + public void onStart() { + mProgressDialog = new ProgressDialog(ReadingActivity.this); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + mProgressDialog.setCancelable(false); + mProgressDialog.setIndeterminate(true); + mProgressDialog.setMessage(getString(R.string.loading)); + mProgressDialog.show(); + } - private class PageLoader extends AsyncTask { + @Override + public void onNext(@Nullable ReaderInfo item) { + if (item == null || item.getTitle().isEmpty() || item.getBody().isEmpty()) { + setText(getString(R.string.untitled), getString(R.string.loading_failed)); + } else { + setText(item.getTitle(), item.getBody()); + } + } - private final WeakReference mActivityReference; - private String mTitleText; - private String mBodyText; + @Override + public void onError(@NonNull Throwable throwable) { + setText(getString(R.string.untitled), getString(R.string.loading_failed)); + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.dismiss(); + mProgressDialog = null; + } + } - public PageLoader(Activity activity) { - mActivityReference = new WeakReference<>(activity); - } + @Override + public void onComplete() { + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.dismiss(); + mProgressDialog = null; + } + } + }); + return true; + } - @Override - protected void onPreExecute() { - super.onPreExecute(); - Activity activity = mActivityReference.get(); - if (activity != null) { - mProgressDialog = new ProgressDialog(activity); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - mProgressDialog.setCancelable(false); - mProgressDialog.setIndeterminate(true); - mProgressDialog.setMessage(activity.getString(R.string.loading)); - mProgressDialog.show(); + private static Observable loadPage(@NonNull final String url) { + return Observable.create(new Action() { + @Override + public void onSubscribe(@NonNull OnSubscribe onSubscribe) { + HtmlFetcher fetcher = new HtmlFetcher(); + try { + JResult result = fetcher.fetchAndExtract(url, 2500, true); + onSubscribe.onNext(new ReaderInfo(result.getTitle(), result.getText())); + } catch (Exception e) { + onSubscribe.onError(new Throwable("Encountered exception")); + e.printStackTrace(); + } catch (OutOfMemoryError e) { + System.gc(); + onSubscribe.onError(new Throwable("Out of memory")); + e.printStackTrace(); + } + onSubscribe.onComplete(); } - } + }); + } - @Override - protected Void doInBackground(String... params) { - - HtmlFetcher fetcher = new HtmlFetcher(); - try { - JResult result = fetcher.fetchAndExtract(params[0], 2500, true); - mTitleText = result.getTitle(); - mBodyText = result.getText(); - } catch (Exception e) { - mTitleText = ""; - mBodyText = ""; - e.printStackTrace(); - } catch (OutOfMemoryError e) { - System.gc(); - mTitleText = ""; - mBodyText = ""; - e.printStackTrace(); - } - return null; + private static class ReaderInfo { + @NonNull private final String mTitleText; + @NonNull private final String mBodyText; + + public ReaderInfo(@NonNull String title, @NonNull String body) { + mTitleText = title; + mBodyText = body; } - @Override - protected void onPostExecute(Void result) { - if (mProgressDialog != null && mProgressDialog.isShowing()) { - mProgressDialog.dismiss(); - mProgressDialog = null; - } - if (mTitleText.isEmpty() || mBodyText.isEmpty()) { - setText(getString(R.string.untitled), getString(R.string.loading_failed)); - } else { - setText(mTitleText, mBodyText); - } - super.onPostExecute(result); + @NonNull + public String getTitle() { + return mTitleText; } + @NonNull + public String getBody() { + return mBodyText; + } } private void setText(String title, String body) { @@ -235,11 +260,12 @@ public class ReadingActivity extends AppCompatActivity { @Override protected void onDestroy() { + mPageLoaderSubscription.unsubscribe(); + if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); mProgressDialog = null; } - mLoaderReference.cancel(true); super.onDestroy(); } diff --git a/app/src/main/java/acr/browser/lightning/activity/TabsManager.java b/app/src/main/java/acr/browser/lightning/activity/TabsManager.java index 04949b1..bcf9392 100644 --- a/app/src/main/java/acr/browser/lightning/activity/TabsManager.java +++ b/app/src/main/java/acr/browser/lightning/activity/TabsManager.java @@ -24,9 +24,9 @@ import acr.browser.lightning.R; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.react.Action; +import acr.browser.lightning.react.OnSubscribe; import acr.browser.lightning.react.Schedulers; import acr.browser.lightning.react.Subscriber; -import acr.browser.lightning.react.Subscription; import acr.browser.lightning.utils.FileUtils; import acr.browser.lightning.react.Observable; import acr.browser.lightning.view.LightningView; @@ -66,14 +66,14 @@ public class TabsManager { final boolean incognito) { return Observable.create(new Action() { @Override - public void onSubscribe(@NonNull final Subscriber subscriber) { + public void onSubscribe(@NonNull final OnSubscribe onSubscribe) { // If incognito, only create one tab, do not handle intent // in order to protect user privacy if (incognito && mTabList.isEmpty()) { newTab(activity, null, true); - subscriber.onComplete(); + onSubscribe.onComplete(); return; } @@ -85,7 +85,7 @@ public class TabsManager { mTabList.clear(); mCurrentTab = null; if (mPreferenceManager.getRestoreLostTabsEnabled()) { - restoreLostTabs(url, activity, subscriber); + restoreLostTabs(url, activity, onSubscribe); } } @@ -94,9 +94,9 @@ public class TabsManager { } private void restoreLostTabs(final String url, final Activity activity, - final Subscriber subscriber) { + final OnSubscribe onSubscribe) { restoreState().subscribeOn(Schedulers.worker()) - .observeOn(Schedulers.main()).subscribe(new Subscription() { + .observeOn(Schedulers.main()).subscribe(new Subscriber() { @Override public void onNext(Bundle item) { LightningView tab = newTab(activity, "", false); @@ -127,7 +127,7 @@ public class TabsManager { if (mTabList.size() == 0) { newTab(activity, null, false); } - subscriber.onComplete(); + onSubscribe.onComplete(); } }); } @@ -331,17 +331,17 @@ public class TabsManager { private Observable restoreState() { return Observable.create(new Action() { @Override - public void onSubscribe(@NonNull Subscriber subscriber) { + public void onSubscribe(@NonNull OnSubscribe onSubscribe) { Bundle savedState = FileUtils.readBundleFromStorage(mApp, BUNDLE_STORAGE); if (savedState != null) { Log.d(Constants.TAG, "Restoring previous WebView state now"); for (String key : savedState.keySet()) { if (key.startsWith(BUNDLE_KEY)) { - subscriber.onNext(savedState.getBundle(key)); + onSubscribe.onNext(savedState.getBundle(key)); } } } - subscriber.onComplete(); + onSubscribe.onComplete(); } }); } diff --git a/app/src/main/java/acr/browser/lightning/react/Action.java b/app/src/main/java/acr/browser/lightning/react/Action.java index 0c1a22e..461e04d 100644 --- a/app/src/main/java/acr/browser/lightning/react/Action.java +++ b/app/src/main/java/acr/browser/lightning/react/Action.java @@ -4,13 +4,13 @@ import android.support.annotation.NonNull; public interface Action { /** - * Should be overridden to send the subscriber - * events such as {@link Subscriber#onNext(Object)} - * or {@link Subscriber#onComplete()}. + * Should be overridden to send the onSubscribe + * events such as {@link OnSubscribe#onNext(Object)} + * or {@link OnSubscribe#onComplete()}. * - * @param subscriber the subscriber that is sent in + * @param onSubscribe the onSubscribe that is sent in * when the user of the Observable * subscribes. */ - void onSubscribe(@NonNull Subscriber subscriber); + void onSubscribe(@NonNull OnSubscribe onSubscribe); } diff --git a/app/src/main/java/acr/browser/lightning/react/Observable.java b/app/src/main/java/acr/browser/lightning/react/Observable.java index 85f3452..0935102 100644 --- a/app/src/main/java/acr/browser/lightning/react/Observable.java +++ b/app/src/main/java/acr/browser/lightning/react/Observable.java @@ -22,8 +22,8 @@ public class Observable { private static final String TAG = Observable.class.getSimpleName(); @NonNull private final Action mAction; - @Nullable private Executor mSubscriber; - @Nullable private Executor mObserver; + @Nullable private Executor mSubscriberThread; + @Nullable private Executor mObserverThread; @NonNull private final Executor mDefault; private Observable(@NonNull Action action) { @@ -49,14 +49,14 @@ public class Observable { } /** - * Tells the Observable what Executor that the subscription + * Tells the Observable what Executor that the subscriber * work should run on. * * @param subscribeExecutor the Executor to run the work on. * @return returns this so that calls can be conveniently chained. */ public Observable subscribeOn(@NonNull Executor subscribeExecutor) { - mSubscriber = subscribeExecutor; + mSubscriberThread = subscribeExecutor; return this; } @@ -68,7 +68,7 @@ public class Observable { * @return returns this so that calls can be conveniently chained. */ public Observable observeOn(@NonNull Executor observerExecutor) { - mObserver = observerExecutor; + mObserverThread = observerExecutor; return this; } @@ -80,10 +80,16 @@ public class Observable { executeOnSubscriberThread(new Runnable() { @Override public void run() { - mAction.onSubscribe(new Subscriber() { + mAction.onSubscribe(new OnSubscribe(null) { + @Override + public void unsubscribe() {} + @Override public void onComplete() {} + @Override + public void start() {} + @Override public void onError(@NonNull Throwable throwable) {} @@ -96,123 +102,140 @@ public class Observable { /** * Immediately subscribes to the Observable and starts - * sending events from the Observable to the {@link Subscription}. + * sending events from the Observable to the {@link Subscriber}. * - * @param subscription the class that wishes to receive onNext and - * onComplete callbacks from the Observable. + * @param subscriber the class that wishes to receive onNext and + * onComplete callbacks from the Observable. */ - public void subscribe(@NonNull final Subscription subscription) { - Preconditions.checkNonNull(subscription); - executeOnSubscriberThread(new Runnable() { + public Subscription subscribe(@NonNull Subscriber subscriber) { + + Preconditions.checkNonNull(subscriber); + + final OnSubscribe onSubscribe = new OnSubscribe(subscriber) { + + @Override + public void unsubscribe() { + setSubscriber(null); + } private boolean mOnCompleteExecuted = false; @Override - public void run() { + public void onComplete() { + Subscriber subscription = getSubscriber(); + if (!mOnCompleteExecuted && subscription != null) { + mOnCompleteExecuted = true; + executeOnObserverThread(new OnCompleteRunnable<>(subscription)); + } else { + Log.e(TAG, "onComplete called more than once"); + throw new RuntimeException("onComplete called more than once"); + } + } + + @Override + public void start() { + Subscriber subscription = getSubscriber(); executeOnObserverThread(new OnStartRunnable<>(subscription)); - mAction.onSubscribe(new Subscriber() { - @Override - public void onComplete() { - if (!mOnCompleteExecuted) { - mOnCompleteExecuted = true; - executeOnObserverThread(new OnCompleteRunnable<>(subscription)); - } else { - Log.e(TAG, "onComplete called more than once"); - throw new RuntimeException("onComplete called more than once"); - } - } + } - @Override - public void onError(@NonNull final Throwable throwable) { - if (!mOnCompleteExecuted) { - mOnCompleteExecuted = true; - executeOnObserverThread(new OnErrorRunnable<>(subscription, throwable)); - } else { - Log.e(TAG, "onComplete already called"); - throw new RuntimeException("onComplete already called"); - } - } + @Override + public void onError(@NonNull final Throwable throwable) { + Subscriber subscription = getSubscriber(); + if (!mOnCompleteExecuted && subscription != null) { + mOnCompleteExecuted = true; + executeOnObserverThread(new OnErrorRunnable<>(subscription, throwable)); + } else { + Log.e(TAG, "onComplete already called"); + throw new RuntimeException("onComplete already called"); + } + } - @Override - public void onNext(final T item) { - if (!mOnCompleteExecuted) { - executeOnObserverThread(new OnNextRunnable<>(subscription, item)); - } else { - Log.e(TAG, "onComplete has been already called, onNext should not be called"); - throw new RuntimeException("onNext should not be called after onComplete has been called"); - } - } - }); + @Override + public void onNext(final T item) { + Subscriber subscription = getSubscriber(); + if (!mOnCompleteExecuted && subscription != null) { + executeOnObserverThread(new OnNextRunnable<>(subscription, item)); + } else { + Log.e(TAG, "onComplete has been already called, onNext should not be called"); + throw new RuntimeException("onNext should not be called after onComplete has been called"); + } + } + }; + executeOnSubscriberThread(new Runnable() { + @Override + public void run() { + mAction.onSubscribe(onSubscribe); } }); + return onSubscribe; } private void executeOnObserverThread(@NonNull Runnable runnable) { - if (mObserver != null) { - mObserver.execute(runnable); + if (mObserverThread != null) { + mObserverThread.execute(runnable); } else { mDefault.execute(runnable); } } private void executeOnSubscriberThread(@NonNull Runnable runnable) { - if (mSubscriber != null) { - mSubscriber.execute(runnable); + if (mSubscriberThread != null) { + mSubscriberThread.execute(runnable); } else { mDefault.execute(runnable); } } private static class OnCompleteRunnable implements Runnable { - private final Subscription subscription; + private final Subscriber subscriber; - public OnCompleteRunnable(Subscription subscription) {this.subscription = subscription;} + public OnCompleteRunnable(Subscriber subscriber) {this.subscriber = subscriber;} @Override public void run() { - subscription.onComplete(); + subscriber.onComplete(); } } private static class OnNextRunnable implements Runnable { - private final Subscription subscription; + private final Subscriber subscriber; private final T item; - public OnNextRunnable(Subscription subscription, T item) { - this.subscription = subscription; + public OnNextRunnable(Subscriber subscriber, T item) { + this.subscriber = subscriber; this.item = item; } @Override public void run() { - subscription.onNext(item); + subscriber.onNext(item); } } private static class OnErrorRunnable implements Runnable { - private final Subscription subscription; + private final Subscriber subscriber; private final Throwable throwable; - public OnErrorRunnable(Subscription subscription, Throwable throwable) { - this.subscription = subscription; + public OnErrorRunnable(Subscriber subscriber, Throwable throwable) { + this.subscriber = subscriber; this.throwable = throwable; } @Override public void run() { - subscription.onError(throwable); + subscriber.onError(throwable); } } private static class OnStartRunnable implements Runnable { - private final Subscription subscription; + private final Subscriber subscriber; - public OnStartRunnable(Subscription subscription) {this.subscription = subscription;} + public OnStartRunnable(Subscriber subscriber) {this.subscriber = subscriber;} @Override public void run() { - subscription.onStart(); + subscriber.onStart(); } } } diff --git a/app/src/main/java/acr/browser/lightning/react/OnSubscribe.java b/app/src/main/java/acr/browser/lightning/react/OnSubscribe.java new file mode 100644 index 0000000..a236661 --- /dev/null +++ b/app/src/main/java/acr/browser/lightning/react/OnSubscribe.java @@ -0,0 +1,59 @@ +package acr.browser.lightning.react; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +public abstract class OnSubscribe implements Subscription { + + @Nullable private Subscriber mSubscriber; + + public OnSubscribe(@Nullable Subscriber subscriber) { + mSubscriber = subscriber; + start(); + } + + public abstract void start(); + + @Nullable + public Subscriber getSubscriber() { + return mSubscriber; + } + + public void setSubscriber(@Nullable Subscriber subscriber) { + mSubscriber = subscriber; + } + + /** + * Called when the observable + * runs into an error that will + * cause it to abort and not finish. + * Receiving this callback means that + * the observable is dead and no + * {@link #onComplete()} or {@link #onNext(Object)} + * callbacks will be called. + * + * @param throwable an optional throwable that could + * be sent. + */ + public abstract void onError(@NonNull Throwable throwable); + + /** + * Called when the Observer emits an + * item. It can be called multiple times. + * It cannot be called after onComplete + * has been called. + * + * @param item the item that has been emitted, + * can be null. + */ + public abstract void onNext(@Nullable T item); + + /** + * This method is called when the observer is + * finished sending the subscriber events. It + * is guaranteed that no other methods will be + * called on the Subscriber after this method + * has been called. + */ + public abstract void onComplete(); +} diff --git a/app/src/main/java/acr/browser/lightning/react/Subscriber.java b/app/src/main/java/acr/browser/lightning/react/Subscriber.java index 8b26f77..d996abd 100644 --- a/app/src/main/java/acr/browser/lightning/react/Subscriber.java +++ b/app/src/main/java/acr/browser/lightning/react/Subscriber.java @@ -3,7 +3,7 @@ package acr.browser.lightning.react; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -public interface Subscriber { +public abstract class Subscriber { /** * Called when the observable @@ -17,7 +17,13 @@ public interface Subscriber { * @param throwable an optional throwable that could * be sent. */ - void onError(@NonNull Throwable throwable); + public void onError(@NonNull Throwable throwable) {} + + /** + * Called before the observer begins + * to process and emit items or complete. + */ + public void onStart() {} /** * Called when the Observer emits an @@ -28,14 +34,14 @@ public interface Subscriber { * @param item the item that has been emitted, * can be null. */ - void onNext(@Nullable T item); + public void onNext(@Nullable T item) {} /** * This method is called when the observer is * finished sending the subscriber events. It * is guaranteed that no other methods will be - * called on the Subscription after this method + * called on the Subscriber after this method * has been called. */ - void onComplete(); + public void onComplete() {} } diff --git a/app/src/main/java/acr/browser/lightning/react/Subscription.java b/app/src/main/java/acr/browser/lightning/react/Subscription.java index 6daa676..627b60b 100644 --- a/app/src/main/java/acr/browser/lightning/react/Subscription.java +++ b/app/src/main/java/acr/browser/lightning/react/Subscription.java @@ -1,47 +1,7 @@ package acr.browser.lightning.react; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +public interface Subscription { -public abstract class Subscription { + void unsubscribe(); - /** - * Called when the observable - * runs into an error that will - * cause it to abort and not finish. - * Receiving this callback means that - * the observable is dead and no - * {@link #onComplete()} or {@link #onNext(Object)} - * callbacks will be called. - * - * @param throwable an optional throwable that could - * be sent. - */ - public void onError(@NonNull Throwable throwable) {} - - /** - * Called before the observer begins - * to process and emit items or complete. - */ - public void onStart() {} - - /** - * Called when the Observer emits an - * item. It can be called multiple times. - * It cannot be called after onComplete - * has been called. - * - * @param item the item that has been emitted, - * can be null. - */ - public void onNext(@Nullable T item) {} - - /** - * This method is called when the observer is - * finished sending the subscriber events. It - * is guaranteed that no other methods will be - * called on the Subscription after this method - * has been called. - */ - public void onComplete() {} } diff --git a/app/src/main/java/acr/browser/lightning/view/LightningView.java b/app/src/main/java/acr/browser/lightning/view/LightningView.java index dae0406..9d19100 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningView.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningView.java @@ -55,8 +55,8 @@ import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.react.Action; import acr.browser.lightning.react.Observable; import acr.browser.lightning.react.Schedulers; +import acr.browser.lightning.react.OnSubscribe; import acr.browser.lightning.react.Subscriber; -import acr.browser.lightning.react.Subscription; import acr.browser.lightning.utils.ProxyUtils; import acr.browser.lightning.utils.ThemeUtils; import acr.browser.lightning.utils.UrlUtils; @@ -375,7 +375,7 @@ public class LightningView { getPathObservable("appcache") .subscribeOn(Schedulers.worker()) - .subscribe(new Subscription() { + .subscribe(new Subscriber() { @Override public void onNext(File item) { settings.setAppCachePath(item.getPath()); @@ -387,7 +387,7 @@ public class LightningView { getPathObservable("geolocation") .subscribeOn(Schedulers.worker()) - .subscribe(new Subscription() { + .subscribe(new Subscriber() { @Override public void onNext(File item) { settings.setGeolocationDatabasePath(item.getPath()); @@ -399,7 +399,7 @@ public class LightningView { getPathObservable("databases") .subscribeOn(Schedulers.worker()) - .subscribe(new Subscription() { + .subscribe(new Subscriber() { @Override public void onNext(File item) { if (API < Build.VERSION_CODES.KITKAT) { @@ -417,10 +417,10 @@ public class LightningView { private Observable getPathObservable(final String subFolder) { return Observable.create(new Action() { @Override - public void onSubscribe(@NonNull Subscriber subscriber) { + public void onSubscribe(@NonNull OnSubscribe onSubscribe) { File file = BrowserApp.get(mActivity).getDir(subFolder, 0); - subscriber.onNext(file); - subscriber.onComplete(); + onSubscribe.onNext(file); + onSubscribe.onComplete(); } }); }