Prevent observers from sending events out of order, add documentation, annotations
This commit is contained in:
parent
84627b3fae
commit
ac3f43a76f
@ -20,7 +20,7 @@ public class IncognitoActivity extends BrowserActivity {
|
|||||||
public Observable<Void> updateCookiePreference() {
|
public Observable<Void> updateCookiePreference() {
|
||||||
return Observable.create(new Action<Void>() {
|
return Observable.create(new Action<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Subscriber<Void> subscriber) {
|
public void onSubscribe(@NonNull Subscriber<Void> subscriber) {
|
||||||
CookieManager cookieManager = CookieManager.getInstance();
|
CookieManager cookieManager = CookieManager.getInstance();
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
CookieSyncManager.createInstance(IncognitoActivity.this);
|
CookieSyncManager.createInstance(IncognitoActivity.this);
|
||||||
|
@ -20,7 +20,7 @@ public class MainActivity extends BrowserActivity {
|
|||||||
public Observable<Void> updateCookiePreference() {
|
public Observable<Void> updateCookiePreference() {
|
||||||
return Observable.create(new Action<Void>() {
|
return Observable.create(new Action<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Subscriber<Void> subscriber) {
|
public void onSubscribe(@NonNull Subscriber<Void> subscriber) {
|
||||||
CookieManager cookieManager = CookieManager.getInstance();
|
CookieManager cookieManager = CookieManager.getInstance();
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
CookieSyncManager.createInstance(MainActivity.this);
|
CookieSyncManager.createInstance(MainActivity.this);
|
||||||
|
@ -17,7 +17,6 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import acr.browser.lightning.app.BrowserApp;
|
|
||||||
import acr.browser.lightning.constant.Constants;
|
import acr.browser.lightning.constant.Constants;
|
||||||
import acr.browser.lightning.database.HistoryItem;
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
import acr.browser.lightning.utils.Utils;
|
import acr.browser.lightning.utils.Utils;
|
||||||
|
@ -3,5 +3,14 @@ package acr.browser.lightning.react;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
public interface Action<T> {
|
public interface Action<T> {
|
||||||
|
/**
|
||||||
|
* Should be overridden to send the subscriber
|
||||||
|
* events such as {@link Subscriber#onNext(Object)}
|
||||||
|
* or {@link Subscriber#onComplete()}.
|
||||||
|
*
|
||||||
|
* @param subscriber the subscriber that is sent in
|
||||||
|
* when the user of the Observable
|
||||||
|
* subscribes.
|
||||||
|
*/
|
||||||
void onSubscribe(@NonNull Subscriber<T> subscriber);
|
void onSubscribe(@NonNull Subscriber<T> subscriber);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package acr.browser.lightning.react;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ import acr.browser.lightning.utils.Preconditions;
|
|||||||
*/
|
*/
|
||||||
public class Observable<T> {
|
public class Observable<T> {
|
||||||
|
|
||||||
|
private static final String TAG = Observable.class.getSimpleName();
|
||||||
|
|
||||||
@NonNull private Action<T> mAction;
|
@NonNull private Action<T> mAction;
|
||||||
@Nullable private Executor mSubscriber;
|
@Nullable private Executor mSubscriber;
|
||||||
@Nullable private Executor mObserver;
|
@Nullable private Executor mObserver;
|
||||||
@ -30,54 +33,99 @@ public class Observable<T> {
|
|||||||
mDefault = new ThreadExecutor(looper);
|
mDefault = new ThreadExecutor(looper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static creator method that creates an Observable from the
|
||||||
|
* {@link Action} that is passed in as the parameter. Action
|
||||||
|
* must not be null.
|
||||||
|
*
|
||||||
|
* @param action the Action to perform
|
||||||
|
* @param <T> the type that will be emitted to the subscriber
|
||||||
|
* @return a valid non-null Observable.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
public static <T> Observable<T> create(@NonNull Action<T> action) {
|
public static <T> Observable<T> create(@NonNull Action<T> action) {
|
||||||
Preconditions.checkNonNull(action);
|
Preconditions.checkNonNull(action);
|
||||||
return new Observable<>(action);
|
return new Observable<>(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the Observable what Executor that the subscription
|
||||||
|
* 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<T> subscribeOn(@NonNull Executor subscribeExecutor) {
|
public Observable<T> subscribeOn(@NonNull Executor subscribeExecutor) {
|
||||||
mSubscriber = subscribeExecutor;
|
mSubscriber = subscribeExecutor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the Observable what Executor the subscriber should observe
|
||||||
|
* the work on.
|
||||||
|
*
|
||||||
|
* @param observerExecutor the Executor to run to callback on.
|
||||||
|
* @return returns this so that calls can be conveniently chained.
|
||||||
|
*/
|
||||||
public Observable<T> observeOn(@NonNull Executor observerExecutor) {
|
public Observable<T> observeOn(@NonNull Executor observerExecutor) {
|
||||||
mObserver = observerExecutor;
|
mObserver = observerExecutor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes immediately to the Observable and ignores
|
||||||
|
* all onComplete and onNext calls.
|
||||||
|
*/
|
||||||
public void subscribe() {
|
public void subscribe() {
|
||||||
executeOnSubscriberThread(new Runnable() {
|
executeOnSubscriberThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mAction.onSubscribe(new Subscriber<T>() {
|
mAction.onSubscribe(new Subscriber<T>() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(T item) {
|
public void onNext(T item) {}
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immediately subscribes to the Observable and starts
|
||||||
|
* sending events from the Observable to the {@link Subscription}.
|
||||||
|
*
|
||||||
|
* @param subscription the class that wishes to receive onNext and
|
||||||
|
* onComplete callbacks from the Observable.
|
||||||
|
*/
|
||||||
public void subscribe(@NonNull final Subscription<T> subscription) {
|
public void subscribe(@NonNull final Subscription<T> subscription) {
|
||||||
Preconditions.checkNonNull(subscription);
|
Preconditions.checkNonNull(subscription);
|
||||||
executeOnSubscriberThread(new Runnable() {
|
executeOnSubscriberThread(new Runnable() {
|
||||||
|
|
||||||
|
private boolean mOnCompleteExecuted = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mAction.onSubscribe(new Subscriber<T>() {
|
mAction.onSubscribe(new Subscriber<T>() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
executeOnObserverThread(new OnCompleteRunnable(subscription));
|
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
|
@Override
|
||||||
public void onNext(final T item) {
|
public void onNext(final T item) {
|
||||||
executeOnObserverThread(new OnNextRunnable(subscription, 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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,11 +10,21 @@ public class Schedulers {
|
|||||||
private static final Executor sWorker = Executors.newCachedThreadPool();
|
private static final Executor sWorker = Executors.newCachedThreadPool();
|
||||||
private static final Executor sMain = new ThreadExecutor(Looper.getMainLooper());
|
private static final Executor sMain = new ThreadExecutor(Looper.getMainLooper());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The worker thread.
|
||||||
|
*
|
||||||
|
* @return a non-null executor.
|
||||||
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Executor worker() {
|
public static Executor worker() {
|
||||||
return sWorker;
|
return sWorker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main thread.
|
||||||
|
*
|
||||||
|
* @return a non-null executor that does work on the main thread.
|
||||||
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Executor main() {
|
public static Executor main() {
|
||||||
return sMain;
|
return sMain;
|
||||||
|
@ -1,7 +1,25 @@
|
|||||||
package acr.browser.lightning.react;
|
package acr.browser.lightning.react;
|
||||||
|
|
||||||
public interface Subscriber<T> {
|
import android.support.annotation.Nullable;
|
||||||
void onNext(T item);
|
|
||||||
|
|
||||||
|
public interface Subscriber<T> {
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
void onComplete();
|
void onComplete();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,26 @@
|
|||||||
package acr.browser.lightning.react;
|
package acr.browser.lightning.react;
|
||||||
|
|
||||||
public interface Subscription<T> {
|
import android.support.annotation.Nullable;
|
||||||
void onNext(T item);
|
|
||||||
|
|
||||||
|
public interface Subscription<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
void onComplete();
|
void onComplete();
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ public class LightningView {
|
|||||||
private Observable<File> getPathObservable(final String subFolder) {
|
private Observable<File> getPathObservable(final String subFolder) {
|
||||||
return Observable.create(new Action<File>() {
|
return Observable.create(new Action<File>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Subscriber<File> subscriber) {
|
public void onSubscribe(@NonNull Subscriber<File> subscriber) {
|
||||||
File file = BrowserApp.get(mActivity).getDir(subFolder, 0);
|
File file = BrowserApp.get(mActivity).getDir(subFolder, 0);
|
||||||
subscriber.onNext(file);
|
subscriber.onNext(file);
|
||||||
subscriber.onComplete();
|
subscriber.onComplete();
|
||||||
|
Loading…
Reference in New Issue
Block a user