From 718493d4928b192119cc443622c796b516d4a5da Mon Sep 17 00:00:00 2001 From: Fabin Paul Date: Wed, 16 Mar 2016 15:32:45 +0530 Subject: [PATCH 001/108] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bc599dc..58a774e8 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Since it was a presentation, Jake only put up the most important code snippets i ### Orchestrating Observables. Make parallel network calls, then combine the result into a single data point (flatmap + zip) -The below ascii diagram expresses the intention of our next example with panache. f1,f2,3,f4,f5 are essentially network calls that when made, give back a result that's needed for a future calculation. +The below ascii diagram expresses the intention of our next example with panache. f1,f2,f3,f4,f5 are essentially network calls that when made, give back a result that's needed for a future calculation. (flatmap) From 6a7f657285cf04b413ef4d7ec88eceec849540c4 Mon Sep 17 00:00:00 2001 From: Kaushik Gopal Date: Thu, 7 Apr 2016 23:35:21 -0700 Subject: [PATCH 002/108] --wip-- --- app/build.gradle | 15 +++++++++++---- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b4654798..39713e83 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,15 +26,18 @@ dependencies { } android { - compileSdkVersion 23 - buildToolsVersion '23.0.2' + compileSdkVersion 'android-N' + buildToolsVersion '24.0.0-rc1' defaultConfig { applicationId "com.morihacky.android.rxjava" - minSdkVersion 15 - targetSdkVersion 22 + minSdkVersion 'N' + targetSdkVersion 'N' versionCode 1 versionName "1.0" + jackOptions { + enabled true + } } buildTypes { release { @@ -42,4 +45,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 69e94a11..93757fe5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.1' + classpath 'com.android.tools.build:gradle:2.1.0-alpha5' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6d8cccc2..8b688c92 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Feb 25 15:10:50 PST 2016 +#Thu Apr 07 23:27:28 PDT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip From a1cd646cf546e9ea773882c9af2f16886641cc30 Mon Sep 17 00:00:00 2001 From: Kaushik Gopal Date: Fri, 8 Apr 2016 00:04:52 -0700 Subject: [PATCH 003/108] chore: upgrade to jack compiler + ref: to lambdas and meth refs --- .../rxjava/fragments/BufferDemoFragment.java | 25 +-- ...ConcurrencyWithSchedulersDemoFragment.java | 26 ++- .../DebounceSearchEmitterFragment.java | 28 ++-- .../DoubleBindingTextViewFragment.java | 14 +- .../fragments/ExponentialBackoffFragment.java | 51 ++---- .../FormValidationCombineLatestFragment.java | 46 +++--- .../rxjava/fragments/PollingFragment.java | 151 ++++++++---------- .../fragments/PseudoCacheConcatFragment.java | 11 +- .../fragments/PseudoCacheMergeFragment.java | 17 +- .../RetrofitAsyncTaskDeathFragment.java | 2 +- .../rxjava/fragments/RetrofitFragment.java | 42 ++--- .../fragments/RotationPersist1Fragment.java | 12 +- .../RotationPersist1WorkerFragment.java | 8 +- .../fragments/RotationPersist2Fragment.java | 53 +++--- .../RotationPersist2WorkerFragment.java | 19 +-- .../rxjava/fragments/TimeoutDemoFragment.java | 12 +- .../rxjava/fragments/TimingDemoFragment.java | 12 +- .../rxjava/retrofit/GithubService.java | 25 ++- .../rxbus/RxBusDemo_Bottom1Fragment.java | 10 +- .../rxbus/RxBusDemo_Bottom2Fragment.java | 17 +- .../rxbus/RxBusDemo_Bottom3Fragment.java | 31 ++-- .../rxjava/volley/VolleyDemoFragment.java | 32 ++-- 22 files changed, 230 insertions(+), 414 deletions(-) diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/BufferDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/BufferDemoFragment.java index 79262789..d52e3571 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/BufferDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/BufferDemoFragment.java @@ -11,7 +11,6 @@ import android.widget.ListView; import com.jakewharton.rxbinding.view.RxView; -import com.jakewharton.rxbinding.view.ViewClickEvent; import com.morihacky.android.rxjava.R; import com.morihacky.android.rxjava.wiring.LogAdapter; @@ -24,7 +23,6 @@ import rx.Observer; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import timber.log.Timber; /** @@ -89,13 +87,10 @@ public View onCreateView(LayoutInflater inflater, private Subscription _getBufferedSubscription() { return RxView.clickEvents(_tapBtn) - .map(new Func1() { - @Override - public Integer call(ViewClickEvent onClickEvent) { - Timber.d("--------- GOT A TAP"); - _log("GOT A TAP"); - return 1; - } + .map(onClickEvent -> { + Timber.d("--------- GOT A TAP"); + _log("GOT A TAP"); + return 1; }) .buffer(2, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) @@ -130,7 +125,7 @@ public void onNext(List integers) { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } @@ -144,13 +139,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/ConcurrencyWithSchedulersDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/ConcurrencyWithSchedulersDemoFragment.java index dec37204..41d2c9d8 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/ConcurrencyWithSchedulersDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/ConcurrencyWithSchedulersDemoFragment.java @@ -25,7 +25,6 @@ import rx.Observer; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import rx.schedulers.Schedulers; import timber.log.Timber; @@ -74,13 +73,10 @@ public void startLongOperation() { } private Observable _getObservable() { - return Observable.just(true).map(new Func1() { - @Override - public Boolean call(Boolean aBoolean) { - _log("Within Observable"); - _doSomeLongOperation_thatBlocksCurrentThread(); - return aBoolean; - } + return Observable.just(true).map(aBoolean -> { + _log("Within Observable"); + _doSomeLongOperation_thatBlocksCurrentThread(); + return aBoolean; }); } @@ -137,20 +133,16 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } private void _setupLogger() { - _logs = new ArrayList(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _logs = new ArrayList<>(); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/DebounceSearchEmitterFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/DebounceSearchEmitterFragment.java index 791fad24..aa105020 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/DebounceSearchEmitterFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/DebounceSearchEmitterFragment.java @@ -23,13 +23,12 @@ import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import co.kaush.core.util.CoreNullnessUtils; import rx.Observer; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import timber.log.Timber; +import static co.kaush.core.util.CoreNullnessUtils.isNotNullOrEmpty; import static java.lang.String.format; public class DebounceSearchEmitterFragment @@ -71,15 +70,10 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); _setupLogger(); - _subscription = RxTextView.textChangeEvents(_inputSearchText)// + _subscription = RxTextView.textChangeEvents(_inputSearchText) .debounce(400, TimeUnit.MILLISECONDS)// default Scheduler is Computation - .filter(new Func1() { - @Override - public Boolean call(TextViewTextChangeEvent changes) { - return CoreNullnessUtils.isNotNullOrEmpty(_inputSearchText.getText().toString()); - } - }) - .observeOn(AndroidSchedulers.mainThread())// + .filter(changes -> isNotNullOrEmpty(_inputSearchText.getText().toString())) + .observeOn(AndroidSchedulers.mainThread()) .subscribe(_getSearchObserver()); } @@ -110,8 +104,8 @@ public void onNext(TextViewTextChangeEvent onTextChangeEvent) { // Method that help wiring up the example (irrelevant to RxJava) private void _setupLogger() { - _logs = new ArrayList(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _logs = new ArrayList<>(); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } @@ -125,13 +119,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/DoubleBindingTextViewFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/DoubleBindingTextViewFragment.java index fa4e4601..a79fb2b5 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/DoubleBindingTextViewFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/DoubleBindingTextViewFragment.java @@ -14,7 +14,6 @@ import butterknife.ButterKnife; import butterknife.OnTextChanged; import rx.Subscription; -import rx.functions.Action1; import rx.subjects.PublishSubject; import static android.text.TextUtils.isEmpty; @@ -37,12 +36,11 @@ public View onCreateView(LayoutInflater inflater, ButterKnife.bind(this, layout); _resultEmitterSubject = PublishSubject.create(); - _subscription = _resultEmitterSubject.asObservable().subscribe(new Action1() { - @Override - public void call(Float aFloat) { - _result.setText(String.valueOf(aFloat)); - } - }); + _subscription = _resultEmitterSubject// + .asObservable()// + .subscribe(aFloat -> { + _result.setText(String.valueOf(aFloat)); + }); onNumberChanged(); _number2.requestFocus(); @@ -50,7 +48,7 @@ public void call(Float aFloat) { return layout; } - @OnTextChanged({ R.id.double_binding_num1, R.id.double_binding_num2 }) + @OnTextChanged({R.id.double_binding_num1, R.id.double_binding_num2}) public void onNumberChanged() { float num1 = 0; float num2 = 0; diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/ExponentialBackoffFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/ExponentialBackoffFragment.java index e3facad5..a1a6374a 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/ExponentialBackoffFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/ExponentialBackoffFragment.java @@ -20,7 +20,6 @@ import butterknife.OnClick; import rx.Observable; import rx.Observer; -import rx.functions.Action0; import rx.functions.Func1; import rx.observables.MathObservable; import rx.subscriptions.CompositeSubscription; @@ -76,12 +75,8 @@ public void startRetryingWithExponentialBackoffStrategy() { Observable// .error(new RuntimeException("testing")) // always fails .retryWhen(new RetryWithDelay(5, 1000)) // notice this is called only onError (onNext values sent are ignored) - .doOnSubscribe(new Action0() { - @Override - public void call() { - _log("Attempting the impossible 5 times in intervals of 1s"); - } - })// + .doOnSubscribe(() -> + _log("Attempting the impossible 5 times in intervals of 1s"))// .subscribe(new Observer() { @Override public void onCompleted() { @@ -109,28 +104,16 @@ public void startExecutingWithExponentialBackoffDelay() { _subscriptions.add(// Observable.range(1, 4)// - .delay(new Func1>() { - @Override - public Observable call(final Integer integer) { - // Rx-y way of doing the Fibonnaci :P - return MathObservable// - .sumInteger(Observable.range(1, integer)) - .flatMap(new Func1>() { - @Override - public Observable call(Integer targetSecondDelay) { - return Observable.just(integer) - .delay(targetSecondDelay, TimeUnit.SECONDS); - } - }); - } - })// - .doOnSubscribe(new Action0() { - @Override - public void call() { - _log(String.format("Execute 4 tasks with delay - time now: [xx:%02d]", - _getSecondHand())); - } + .delay(integer -> { + // Rx-y way of doing the Fibonnaci :P + return MathObservable// + .sumInteger(Observable.range(1, integer)) + .flatMap(targetSecondDelay -> Observable.just(integer) + .delay(targetSecondDelay, TimeUnit.SECONDS)); })// + .doOnSubscribe(() -> + _log(String.format("Execute 4 tasks with delay - time now: [xx:%02d]", + _getSecondHand())))// .subscribe(new Observer() { @Override public void onCompleted() { @@ -167,7 +150,7 @@ private int _getSecondHand() { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logList.setAdapter(_adapter); } @@ -175,13 +158,9 @@ private void _log(String logMsg) { _logs.add(logMsg); // You can only do below stuff on main thread. - new Handler(getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/FormValidationCombineLatestFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/FormValidationCombineLatestFragment.java index c7841dd7..1a3157bf 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/FormValidationCombineLatestFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/FormValidationCombineLatestFragment.java @@ -16,7 +16,6 @@ import rx.Observable; import rx.Observer; import rx.Subscription; -import rx.functions.Func3; import timber.log.Timber; import static android.text.TextUtils.isEmpty; @@ -65,35 +64,30 @@ private void _combineLatestEvents() { _subscription = Observable.combineLatest(_emailChangeObservable, _passwordChangeObservable, _numberChangeObservable, - new Func3() { - @Override - public Boolean call(CharSequence newEmail, - CharSequence newPassword, - CharSequence newNumber) { - - boolean emailValid = !isEmpty(newEmail) && - EMAIL_ADDRESS.matcher(newEmail).matches(); - if (!emailValid) { - _email.setError("Invalid Email!"); - } - - boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8; - if (!passValid) { - _password.setError("Invalid Password!"); - } + (newEmail, newPassword, newNumber) -> { - boolean numValid = !isEmpty(newNumber); - if (numValid) { - int num = Integer.parseInt(newNumber.toString()); - numValid = num > 0 && num <= 100; - } - if (!numValid) { - _number.setError("Invalid Number!"); - } + boolean emailValid = !isEmpty(newEmail) && + EMAIL_ADDRESS.matcher(newEmail).matches(); + if (!emailValid) { + _email.setError("Invalid Email!"); + } - return emailValid && passValid && numValid; + boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8; + if (!passValid) { + _password.setError("Invalid Password!"); + } + boolean numValid = !isEmpty(newNumber); + if (numValid) { + int num = Integer.parseInt(newNumber.toString()); + numValid = num > 0 && num <= 100; + } + if (!numValid) { + _number.setError("Invalid Number!"); } + + return emailValid && passValid && numValid; + })// .subscribe(new Observer() { @Override diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/PollingFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/PollingFragment.java index fedc9cd6..3f4bb82a 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/PollingFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/PollingFragment.java @@ -22,8 +22,6 @@ import butterknife.ButterKnife; import butterknife.OnClick; import rx.Observable; -import rx.functions.Action0; -import rx.functions.Action1; import rx.functions.Func1; import rx.subscriptions.CompositeSubscription; import timber.log.Timber; @@ -80,24 +78,13 @@ public void onStartSimplePollingClicked() { _subscriptions.add(// Observable.interval(INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS) - .map(new Func1() { - @Override - public String call(Long heartBeat) { - return _doNetworkCallAndGetStringResult(heartBeat); - } - }).take(pollCount) - .doOnSubscribe(new Action0() { - @Override - public void call() { - _log(String.format("Start simple polling - %s", _counter)); - } - }) - .subscribe(new Action1() { - @Override - public void call(String taskName) { - _log(String.format(Locale.US, "Executing polled task [%s] now time : [xx:%02d]", - taskName, _getSecondHand())); - } + .map(this::_doNetworkCallAndGetStringResult)// + .take(pollCount) + .doOnSubscribe(() -> + _log(String.format("Start simple polling - %s", _counter))) + .subscribe(taskName -> { + _log(String.format(Locale.US, "Executing polled task [%s] now time : [xx:%02d]", + taskName, _getSecondHand())); }) ); } @@ -115,17 +102,11 @@ public void onStartIncreasinglyDelayedPolling() { _subscriptions.add(// Observable.just(1) .repeatWhen(new RepeatWithDelay(pollCount, pollingInterval)) - .subscribe(new Action1() { - @Override - public void call(Object o) { - _log(String.format(Locale.US, "Executing polled task now time : [xx:%02d]", - _getSecondHand())); - } - }, new Action1() { - @Override - public void call(Throwable e) { - Timber.d(e, "arrrr. Error"); - } + .subscribe(o -> { + _log(String.format(Locale.US, "Executing polled task now time : [xx:%02d]", + _getSecondHand())); + }, e -> { + Timber.d(e, "arrrr. Error"); }) ); } @@ -140,54 +121,6 @@ public void call(Throwable e) { // It's 12am in the morning and i feel lazy dammit !!! - //public static class RepeatWithDelay - public class RepeatWithDelay - implements Func1, Observable> { - - private final int _repeatLimit; - private final int _pollingInterval; - private int _repeatCount = 1; - - RepeatWithDelay(int repeatLimit, int pollingInterval) { - _pollingInterval = pollingInterval; - _repeatLimit = repeatLimit; - } - - // this is a notificationhandler, all we care about is - // the emission "type" not emission "content" - // only onNext triggers a re-subscription - - @Override - public Observable call(Observable inputObservable) { - - // it is critical to use inputObservable in the chain for the result - // ignoring it and doing your own thing will break the sequence - - return inputObservable.flatMap(new Func1>() { - @Override - public Observable call(Void blah) { - - - if (_repeatCount >= _repeatLimit) { - // terminate the sequence cause we reached the limit - _log("Completing sequence"); - return Observable.empty(); - } - - // since we don't get an input - // we store state in this handler to tell us the point of time we're firing - _repeatCount++; - - return Observable.timer(_repeatCount * _pollingInterval, - TimeUnit.MILLISECONDS); - } - }); - } - } - - // ----------------------------------------------------------------------------------- - // Method that help wiring up the example (irrelevant to RxJava) - private String _doNetworkCallAndGetStringResult(long attempt) { try { if (attempt == 4) { @@ -206,6 +139,9 @@ private String _doNetworkCallAndGetStringResult(long attempt) { return String.valueOf(_counter); } + // ----------------------------------------------------------------------------------- + // Method that help wiring up the example (irrelevant to RxJava) + private int _getSecondHand() { long millis = System.currentTimeMillis(); return (int) (TimeUnit.MILLISECONDS.toSeconds(millis) - @@ -221,20 +157,16 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); _counter = 0; } @@ -243,6 +175,51 @@ private boolean _isCurrentlyOnMainThread() { return Looper.myLooper() == Looper.getMainLooper(); } + //public static class RepeatWithDelay + public class RepeatWithDelay + implements Func1, Observable> { + + private final int _repeatLimit; + private final int _pollingInterval; + private int _repeatCount = 1; + + RepeatWithDelay(int repeatLimit, int pollingInterval) { + _pollingInterval = pollingInterval; + _repeatLimit = repeatLimit; + } + + // this is a notificationhandler, all we care about is + // the emission "type" not emission "content" + // only onNext triggers a re-subscription + + @Override + public Observable call(Observable inputObservable) { + + // it is critical to use inputObservable in the chain for the result + // ignoring it and doing your own thing will break the sequence + + return inputObservable.flatMap(new Func1>() { + @Override + public Observable call(Void blah) { + + + if (_repeatCount >= _repeatLimit) { + // terminate the sequence cause we reached the limit + _log("Completing sequence"); + return Observable.empty(); + } + + // since we don't get an input + // we store state in this handler to tell us the point of time we're firing + _repeatCount++; + + return Observable.timer(_repeatCount * _pollingInterval, + TimeUnit.MILLISECONDS); + } + }); + } + } + private class LogAdapter extends ArrayAdapter { diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java index fbd6f179..e9f85d85 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java @@ -22,9 +22,7 @@ import butterknife.OnClick; import rx.Observable; import rx.Subscriber; -import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import timber.log.Timber; public class PseudoCacheConcatFragment @@ -56,7 +54,7 @@ public void onDemoPseudoCacheClicked() { _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, - new ArrayList()); + new ArrayList<>()); _resultList.setAdapter(_adapter); _initializeCache(); @@ -112,12 +110,7 @@ private Observable _getFreshData() { String githubToken = getResources().getString(R.string.github_oauth_token); GithubApi githubService = GithubService.createGithubService(githubToken); return githubService.contributors("square", "retrofit") - .flatMap(new Func1, Observable>() { - @Override - public Observable call(List contributors) { - return Observable.from(contributors); - } - }); + .flatMap(Observable::from); } private void _initializeCache() { diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheMergeFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheMergeFragment.java index 6c4a6fc6..fc21f5b8 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheMergeFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheMergeFragment.java @@ -24,7 +24,6 @@ import rx.Observable; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import rx.schedulers.Schedulers; import timber.log.Timber; @@ -55,7 +54,7 @@ public void onDestroyView() { @OnClick(R.id.btn_start_pseudo_cache) public void onDemoPseudoCacheClicked() { - _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, new ArrayList()); + _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, new ArrayList<>()); _resultList.setAdapter(_adapter); _initializeCache(); @@ -126,18 +125,8 @@ private Observable> _getFreshData() { GithubApi githubService = GithubService.createGithubService(githubToken); return githubService.contributors("square", "retrofit") - .flatMap(new Func1, Observable>() { - @Override - public Observable call(List contributors) { - return Observable.from(contributors); - } - }) - .map(new Func1>() { - @Override - public Pair call(Contributor contributor) { - return new Pair<>(contributor, System.currentTimeMillis()); - } - }); + .flatMap(Observable::from) + .map(contributor -> new Pair<>(contributor, System.currentTimeMillis())); } private void _initializeCache() { diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitAsyncTaskDeathFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitAsyncTaskDeathFragment.java index 718d9601..5b42e099 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitAsyncTaskDeathFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitAsyncTaskDeathFragment.java @@ -57,7 +57,7 @@ public View onCreateView(LayoutInflater inflater, _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, - new ArrayList()); + new ArrayList<>()); //_adapter.setNotifyOnChange(true); _resultList.setAdapter(_adapter); diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitFragment.java index 04c1dde2..e67695aa 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RetrofitFragment.java @@ -26,8 +26,6 @@ import rx.Observable; import rx.Observer; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; -import rx.functions.Func2; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; import timber.log.Timber; @@ -57,13 +55,13 @@ public void onCreate(Bundle savedInstanceState) { @Override public View onCreateView(LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.fragment_retrofit, container, false); ButterKnife.bind(this, layout); - _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, new ArrayList()); + _adapter = new ArrayAdapter<>(getActivity(), R.layout.item_log, R.id.item_log, new ArrayList<>()); //_adapter.setNotifyOnChange(true); _resultList.setAdapter(_adapter); @@ -123,32 +121,14 @@ public void onListContributorsWithFullUserInfoClicked() { _adapter.clear(); _subscriptions.add(_githubService.contributors(_username.getText().toString(), _repo.getText().toString()) - .flatMap(new Func1, Observable>() { - @Override - public Observable call(List contributors) { - return Observable.from(contributors); - } - }) - .flatMap(new Func1>>() { - @Override - public Observable> call(Contributor contributor) { - Observable _userObservable = _githubService.user(contributor.login) - .filter(new Func1() { - @Override - public Boolean call(User user) { - return !isEmpty(user.name) && !isEmpty(user.email); - } - }); - - return Observable.zip(_userObservable, - Observable.just(contributor), - new Func2>() { - @Override - public Pair call(User user, Contributor contributor) { - return new Pair<>(user, contributor); - } - }); - } + .flatMap(Observable::from) + .flatMap(contributor -> { + Observable _userObservable = _githubService.user(contributor.login) + .filter(user -> !isEmpty(user.name) && !isEmpty(user.email)); + + return Observable.zip(_userObservable, + Observable.just(contributor), + Pair::new); }) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1Fragment.java index 6cde3680..dd48d1b8 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1Fragment.java @@ -120,7 +120,7 @@ public void onDestroyView() { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logList.setAdapter(_adapter); } @@ -128,13 +128,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg); // You can only do below stuff on main thread. - new Handler(getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1WorkerFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1WorkerFragment.java index 4c727e1c..2d3ad1b0 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1WorkerFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist1WorkerFragment.java @@ -11,7 +11,6 @@ import rx.Observable; import rx.Subscription; -import rx.functions.Func1; import rx.observables.ConnectableObservable; public class RotationPersist1WorkerFragment @@ -58,12 +57,7 @@ public void onCreate(Bundle savedInstanceState) { Observable intsObservable =// Observable.interval(1, TimeUnit.SECONDS)// - .map(new Func1() { - @Override - public Integer call(Long aLong) { - return aLong.intValue(); - } - })// + .map(Long::intValue)// .take(20); // ----------------------------------------------------------------------------------- diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2Fragment.java index aadeabb2..ebbd88fc 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2Fragment.java @@ -20,7 +20,6 @@ import butterknife.OnClick; import rx.Observable; import rx.Observer; -import rx.functions.Action0; import rx.subscriptions.CompositeSubscription; import timber.log.Timber; @@ -62,28 +61,24 @@ public void startOperationFromWorkerFrag() { public void setStream(Observable intStream) { _subscriptions.add(// - intStream.doOnSubscribe(new Action0() { - @Override - public void call() { - _log("Subscribing to intsObservable"); - } - }).subscribe(new Observer() { - @Override - public void onCompleted() { - _log("Observable is complete"); - } - - @Override - public void onError(Throwable e) { - Timber.e(e, "Error in worker demo frag observable"); - _log("Dang! something went wrong."); - } - - @Override - public void onNext(Integer integer) { - _log(String.format("Worker frag spits out - %d", integer)); - } - })); + intStream.doOnSubscribe(() -> _log("Subscribing to intsObservable")) + .subscribe(new Observer() { + @Override + public void onCompleted() { + _log("Observable is complete"); + } + + @Override + public void onError(Throwable e) { + Timber.e(e, "Error in worker demo frag observable"); + _log("Dang! something went wrong."); + } + + @Override + public void onNext(Integer integer) { + _log(String.format("Worker frag spits out - %d", integer)); + } + })); } // ----------------------------------------------------------------------------------- @@ -113,7 +108,7 @@ public void onPause() { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logList.setAdapter(_adapter); } @@ -121,13 +116,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg); // You can only do below stuff on main thread. - new Handler(getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } \ No newline at end of file diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2WorkerFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2WorkerFragment.java index 313d7467..9b82f881 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2WorkerFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/RotationPersist2WorkerFragment.java @@ -3,12 +3,14 @@ import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; + import com.morihacky.android.rxjava.MainActivity; + import java.util.List; import java.util.concurrent.TimeUnit; + import rx.Observable; import rx.Subscription; -import rx.functions.Func1; import rx.subjects.PublishSubject; import rx.subjects.Subject; @@ -22,7 +24,7 @@ public class RotationPersist2WorkerFragment /** * Since we're holding a reference to the Master a.k.a Activity/Master Frag * remember to explicitly remove the worker fragment or you'll have a mem leak in your hands. - * + *

* See {@link MainActivity#onBackPressed()} */ @Override @@ -51,15 +53,10 @@ public void onCreate(Bundle savedInstanceState) { // Retain this fragment across configuration changes. setRetainInstance(true); - _storedIntsSubscription =// - Observable.interval(1, TimeUnit.SECONDS)// - .map(new Func1() { - @Override - public Integer call(Long aLong) { - return aLong.intValue(); - } - })// - .take(20)// + _storedIntsSubscription = + Observable.interval(1, TimeUnit.SECONDS) + .map(Long::intValue) + .take(20) .subscribe(_intStream); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimeoutDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimeoutDemoFragment.java index 480a6e20..03e86031 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimeoutDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimeoutDemoFragment.java @@ -150,7 +150,7 @@ public void onNext(String taskType) { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } @@ -164,13 +164,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java index 92556f0e..b34f6f15 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java @@ -184,7 +184,7 @@ public void OnClearLog() { private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } @@ -192,13 +192,9 @@ private void _log(String logMsg) { _logs.add(0, String.format(logMsg + " [MainThread: %b]", getMainLooper() == myLooper())); // You can only do below stuff on main thread. - new Handler(getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java b/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java index 021faa07..de14d432 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java +++ b/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java @@ -2,12 +2,8 @@ import android.text.TextUtils; -import java.io.IOException; - -import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; -import okhttp3.Response; import retrofit2.GsonConverterFactory; import retrofit2.Retrofit; import retrofit2.RxJavaCallAdapterFactory; @@ -16,23 +12,22 @@ public class GithubService { - private GithubService() { } + private GithubService() { + } public static GithubApi createGithubService(final String githubToken) { Retrofit.Builder builder = new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create()) - .addConverterFactory(GsonConverterFactory.create()) - .baseUrl("https://api.github.com"); + .addConverterFactory(GsonConverterFactory.create()) + .baseUrl("https://api.github.com"); if (!TextUtils.isEmpty(githubToken)) { - OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() { - @Override public Response intercept(Chain chain) throws IOException { - Request request = chain.request(); - Request newReq = request.newBuilder() - .addHeader("Authorization", format("token %s", githubToken)) - .build(); - return chain.proceed(newReq); - } + OkHttpClient client = new OkHttpClient.Builder().addInterceptor(chain -> { + Request request = chain.request(); + Request newReq = request.newBuilder() + .addHeader("Authorization", format("token %s", githubToken)) + .build(); + return chain.proceed(newReq); }).build(); builder.client(client); diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java index c46fb544..6fbbfd3e 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java @@ -14,7 +14,6 @@ import butterknife.Bind; import butterknife.ButterKnife; -import rx.functions.Action1; import rx.subscriptions.CompositeSubscription; public class RxBusDemo_Bottom1Fragment @@ -46,12 +45,9 @@ public void onStart() { _subscriptions// .add(_rxBus.toObserverable()// - .subscribe(new Action1() { - @Override - public void call(Object event) { - if (event instanceof RxBusDemoFragment.TapEvent) { - _showTapText(); - } + .subscribe(event -> { + if (event instanceof RxBusDemoFragment.TapEvent) { + _showTapText(); } })); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java index d5beaae2..68570e1e 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java @@ -19,7 +19,6 @@ import butterknife.ButterKnife; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; import rx.subscriptions.CompositeSubscription; public class RxBusDemo_Bottom2Fragment @@ -53,12 +52,9 @@ public void onStart() { Observable tapEventEmitter = _rxBus.toObserverable().share(); _subscriptions// - .add(tapEventEmitter.subscribe(new Action1() { - @Override - public void call(Object event) { - if (event instanceof RxBusDemoFragment.TapEvent) { - _showTapText(); - } + .add(tapEventEmitter.subscribe(event -> { + if (event instanceof RxBusDemoFragment.TapEvent) { + _showTapText(); } })); @@ -68,11 +64,8 @@ public void call(Object event) { _subscriptions// .add(debouncedBufferEmitter// .observeOn(AndroidSchedulers.mainThread())// - .subscribe(new Action1>() { - @Override - public void call(List taps) { - _showTapCount(taps.size()); - } + .subscribe(taps -> { + _showTapCount(taps.size()); })); } diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java index b956d58b..6eb189d1 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java @@ -12,15 +12,11 @@ import com.morihacky.android.rxjava.R; import com.morihacky.android.rxjava.fragments.BaseFragment; -import java.util.List; import java.util.concurrent.TimeUnit; import butterknife.Bind; import butterknife.ButterKnife; -import rx.Observable; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; -import rx.functions.Func1; import rx.observables.ConnectableObservable; import rx.subscriptions.CompositeSubscription; @@ -55,27 +51,18 @@ public void onStart() { ConnectableObservable tapEventEmitter = _rxBus.toObserverable().publish(); _subscriptions// - .add(tapEventEmitter.subscribe(new Action1() { - @Override - public void call(Object event) { - if (event instanceof RxBusDemoFragment.TapEvent) { - _showTapText(); - } + .add(tapEventEmitter.subscribe(event -> { + if (event instanceof RxBusDemoFragment.TapEvent) { + _showTapText(); } })); - _subscriptions// - .add(tapEventEmitter.publish(new Func1, Observable>>() { - @Override - public Observable> call(Observable stream) { - return stream.buffer(stream.debounce(1, TimeUnit.SECONDS)); - } - }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1>() { - @Override - public void call(List taps) { - _showTapCount(taps.size()); - } - })); + _subscriptions + .add(tapEventEmitter.publish(stream -> + stream.buffer(stream.debounce(1, TimeUnit.SECONDS))) + .observeOn(AndroidSchedulers.mainThread()).subscribe(taps -> { + _showTapCount(taps.size()); + })); _subscriptions.add(tapEventEmitter.connect()); diff --git a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java index 2860a85e..7e00d4e5 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java @@ -31,7 +31,6 @@ import rx.Observable; import rx.Observer; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func0; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; import timber.log.Timber; @@ -50,8 +49,8 @@ public class VolleyDemoFragment @Override public View onCreateView(LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.fragment_volley, container, false); ButterKnife.bind(this, layout); return layout; @@ -76,15 +75,12 @@ public void onDestroyView() { } public Observable newGetRouteData() { - return Observable.defer(new Func0>() { - @Override - public Observable call() { - try { - return Observable.just(getRouteData()); - } catch (InterruptedException | ExecutionException e) { - Log.e("routes", e.getMessage()); - return Observable.error(e); - } + return Observable.defer(() -> { + try { + return Observable.just(getRouteData()); + } catch (InterruptedException | ExecutionException e) { + Log.e("routes", e.getMessage()); + return Observable.error(e); } }); } @@ -138,7 +134,7 @@ private JSONObject getRouteData() throws ExecutionException, InterruptedExceptio private void _setupLogger() { _logs = new ArrayList<>(); - _adapter = new LogAdapter(getActivity(), new ArrayList()); + _adapter = new LogAdapter(getActivity(), new ArrayList<>()); _logsList.setAdapter(_adapter); } @@ -152,13 +148,9 @@ private void _log(String logMsg) { _logs.add(0, logMsg + " (NOT main thread) "); // You can only do below stuff on main thread. - new Handler(Looper.getMainLooper()).post(new Runnable() { - - @Override - public void run() { - _adapter.clear(); - _adapter.addAll(_logs); - } + new Handler(Looper.getMainLooper()).post(() -> { + _adapter.clear(); + _adapter.addAll(_logs); }); } } From a89840c1954f2f701bdc16a64033882abba4c18f Mon Sep 17 00:00:00 2001 From: Mitchell Tilbrook Date: Fri, 15 Apr 2016 16:30:56 +1000 Subject: [PATCH 004/108] upgrade: retrofit 2.0.0-beta3 -> 2.0.0 --- app/build.gradle | 6 +++--- .../morihacky/android/rxjava/retrofit/GithubService.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b4654798..bad891a1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,9 +14,9 @@ dependencies { compile 'com.jakewharton.rxbinding:rxbinding:0.2.0' compile 'com.jakewharton:butterknife:7.0.1' compile 'com.jakewharton.timber:timber:2.4.2' - compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3' - compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3' - compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3' + compile 'com.squareup.retrofit2:retrofit:2.0.0' + compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0' + compile 'com.squareup.retrofit2:converter-gson:2.0.0' compile 'com.squareup.okhttp3:okhttp:3.0.1' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.0.1' compile 'com.mcxiaoke.volley:library:1.0.19' diff --git a/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java b/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java index 021faa07..82de2f5b 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java +++ b/app/src/main/java/com/morihacky/android/rxjava/retrofit/GithubService.java @@ -8,9 +8,9 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import retrofit2.GsonConverterFactory; import retrofit2.Retrofit; -import retrofit2.RxJavaCallAdapterFactory; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; import static java.lang.String.format; From 2056294cd485c5804478fed2fb58c80553326dc9 Mon Sep 17 00:00:00 2001 From: Mitchell Tilbrook Date: Fri, 15 Apr 2016 17:09:01 +1000 Subject: [PATCH 005/108] upgrade: build tools, support library, and target api --- app/build.gradle | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b4654798..e12abb50 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,12 @@ apply plugin: 'com.android.application' +buildscript { + ext.android_support = '23.3.0' +} + dependencies { - compile 'com.android.support:support-v13:23.2.1' - compile 'com.android.support:appcompat-v7:23.2.1' + compile "com.android.support:support-v13:$android_support" + compile "com.android.support:appcompat-v7:$android_support" compile 'io.reactivex:rxandroid:1.0.1' // Because RxAndroid releases are few and far between, it is recommended you also @@ -27,12 +31,12 @@ dependencies { android { compileSdkVersion 23 - buildToolsVersion '23.0.2' + buildToolsVersion '23.0.3' defaultConfig { applicationId "com.morihacky.android.rxjava" minSdkVersion 15 - targetSdkVersion 22 + targetSdkVersion 23 versionCode 1 versionName "1.0" } From d3ac5512ea271aa4b427f1d1349e5492bd32cdf2 Mon Sep 17 00:00:00 2001 From: Jose Miguel Mendez Date: Sun, 24 Apr 2016 01:07:13 -0400 Subject: [PATCH 006/108] Removed unused priority variable, was causing confusion If you need to set priority, you have to extend the Request class and override the `getPriority()` function. This seems outside of the scope of this example --- .../com/morihacky/android/rxjava/volley/VolleyDemoFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java index 2860a85e..bb9beaf5 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java @@ -127,7 +127,6 @@ public void onNext(JSONObject jsonObject) { private JSONObject getRouteData() throws ExecutionException, InterruptedException { RequestFuture future = RequestFuture.newFuture(); String url = "http://www.weather.com.cn/adat/sk/101010100.html"; - final Request.Priority priority = Request.Priority.IMMEDIATE; JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, url, future, future); MyVolley.getRequestQueue().add(req); return future.get(); From c2124daa1c89c0d295e332e0f63bcef7c0c63e0f Mon Sep 17 00:00:00 2001 From: Jose Miguel Mendez Date: Sun, 24 Apr 2016 01:18:08 -0400 Subject: [PATCH 007/108] Added Javadoc to give more context Found it a bit confusing trying to wrangle through the code --- .../android/rxjava/volley/VolleyDemoFragment.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java index bb9beaf5..95304c15 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/volley/VolleyDemoFragment.java @@ -75,6 +75,12 @@ public void onDestroyView() { ButterKnife.unbind(this); } + /** + * Creates and returns an observable generated from the Future returned from + * {@code getRouteData()}. The observable can then be subscribed to as shown in + * {@code startVolleyRequest()} + * @return Observable + */ public Observable newGetRouteData() { return Observable.defer(new Func0>() { @Override @@ -123,7 +129,13 @@ public void onNext(JSONObject jsonObject) { } })); } - + /** + * Converts the Asynchronous Request into a Synchronous Future that can be used to + * block via {@code Future.get()}. Observables require blocking/synchronous functions + * @return JSONObject + * @throws ExecutionException + * @throws InterruptedException + */ private JSONObject getRouteData() throws ExecutionException, InterruptedException { RequestFuture future = RequestFuture.newFuture(); String url = "http://www.weather.com.cn/adat/sk/101010100.html"; From a65412698d7b0c283fb16112db8818d0b3f0cffb Mon Sep 17 00:00:00 2001 From: Rashiq Date: Sun, 1 May 2016 14:47:26 +0200 Subject: [PATCH 008/108] Fix typo --- app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBus.java | 2 +- .../android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java | 2 +- .../android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java | 2 +- .../android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBus.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBus.java index 83f61f46..a324b065 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBus.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBus.java @@ -20,7 +20,7 @@ public void send(Object o) { _bus.onNext(o); } - public Observable toObserverable() { + public Observable toObservable() { return _bus; } diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java index c46fb544..7718fce7 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom1Fragment.java @@ -45,7 +45,7 @@ public void onStart() { _subscriptions = new CompositeSubscription(); _subscriptions// - .add(_rxBus.toObserverable()// + .add(_rxBus.toObservable()// .subscribe(new Action1() { @Override public void call(Object event) { diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java index d5beaae2..738b4636 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom2Fragment.java @@ -50,7 +50,7 @@ public void onStart() { super.onStart(); _subscriptions = new CompositeSubscription(); - Observable tapEventEmitter = _rxBus.toObserverable().share(); + Observable tapEventEmitter = _rxBus.toObservable().share(); _subscriptions// .add(tapEventEmitter.subscribe(new Action1() { diff --git a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java index b956d58b..ad3593da 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/rxbus/RxBusDemo_Bottom3Fragment.java @@ -52,7 +52,7 @@ public void onStart() { super.onStart(); _subscriptions = new CompositeSubscription(); - ConnectableObservable tapEventEmitter = _rxBus.toObserverable().publish(); + ConnectableObservable tapEventEmitter = _rxBus.toObservable().publish(); _subscriptions// .add(tapEventEmitter.subscribe(new Action1() { From c29a5d703098b5a8a705e379f4c0721bfb60e753 Mon Sep 17 00:00:00 2001 From: Craig Russell Date: Tue, 3 May 2016 14:05:55 +0100 Subject: [PATCH 009/108] remove duplicate `compile 'io.reactivex:rxjava-math:1.0.0'` was defined twice --- app/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b4654798..ab0bd652 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,6 @@ dependencies { // explicitly depend on RxJava's latest version for bug fixes and new features. compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxjava-math:1.0.0' - compile 'io.reactivex:rxjava-math:1.0.0' compile 'com.github.kaushikgopal:CoreTextUtils:c703fa12b6' compile 'com.jakewharton.rxbinding:rxbinding:0.2.0' compile 'com.jakewharton:butterknife:7.0.1' @@ -42,4 +41,4 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } -} \ No newline at end of file +} From b83abd13e20e397035dc4a24eb4a1105ee6bf418 Mon Sep 17 00:00:00 2001 From: Kaushik Gopal Date: Tue, 17 May 2016 07:54:02 -0700 Subject: [PATCH 010/108] fix: upgrade gradle plugin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 93757fe5..3a089e4b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0-alpha5' + classpath 'com.android.tools.build:gradle:2.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 97721da4b13a028b5b7b29fec8db4eb15b5e6ad0 Mon Sep 17 00:00:00 2001 From: Zhangchong <287424013@qq.com> Date: Fri, 17 Jun 2016 00:13:42 +0800 Subject: [PATCH 011/108] Update PseudoCacheConcatFragment.java set correct scheduler for network request. --- .../android/rxjava/fragments/PseudoCacheConcatFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java index fbd6f179..fd282918 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/PseudoCacheConcatFragment.java @@ -62,6 +62,7 @@ public void onDemoPseudoCacheClicked() { _initializeCache(); Observable.concat(_getCachedData(), _getFreshData()) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber() { @Override From 543e933e851d045e95f6bb6519657c7d029c0a88 Mon Sep 17 00:00:00 2001 From: Kaushik Gopal Date: Thu, 30 Jun 2016 17:18:19 -0700 Subject: [PATCH 012/108] chore: upgrade libs --- app/build.gradle | 4 ++-- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b4654798..015b4791 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,10 +4,10 @@ dependencies { compile 'com.android.support:support-v13:23.2.1' compile 'com.android.support:appcompat-v7:23.2.1' - compile 'io.reactivex:rxandroid:1.0.1' + compile 'io.reactivex:rxandroid:1.2.0' // Because RxAndroid releases are few and far between, it is recommended you also // explicitly depend on RxJava's latest version for bug fixes and new features. - compile 'io.reactivex:rxjava:1.0.14' + compile 'io.reactivex:rxjava:1.1.4' compile 'io.reactivex:rxjava-math:1.0.0' compile 'io.reactivex:rxjava-math:1.0.0' compile 'com.github.kaushikgopal:CoreTextUtils:c703fa12b6' diff --git a/build.gradle b/build.gradle index 69e94a11..facb0aa2 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.1' + classpath 'com.android.tools.build:gradle:2.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6d8cccc2..ed1a3ada 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Feb 25 15:10:50 PST 2016 +#Tue May 17 07:54:26 PDT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip From f3d8a23e6f2f6e55adfb650fadbe856381474b64 Mon Sep 17 00:00:00 2001 From: Kaushik Gopal Date: Thu, 30 Jun 2016 17:24:02 -0700 Subject: [PATCH 013/108] feat: add example for executing task, then with delay --- README.md | 1 + .../rxjava/fragments/TimingDemoFragment.java | 45 +++++++++++++++++-- .../main/res/layout/fragment_demo_timing.xml | 31 +++++++++---- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1bc599dc..2e15bac4 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ Cases demonstrated here: 2. run a task constantly every 1s (there's a delay of 1s before the first task fires off) 3. run a task constantly every 1s (same as above but there's no delay before the first task fires off) 4. run a task constantly every 3s, but after running it 5 times, terminate automatically +5. run a task A, pause for sometime, then execute Task B, then terminate ### Exponential backoff diff --git a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java index 92556f0e..3e05b06e 100644 --- a/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java +++ b/app/src/main/java/com/morihacky/android/rxjava/fragments/TimingDemoFragment.java @@ -24,6 +24,7 @@ import rx.Observable; import rx.Observer; import rx.Subscription; +import rx.functions.Action1; import timber.log.Timber; import static android.os.Looper.getMainLooper; @@ -66,7 +67,7 @@ public void onDestroyView() { // ----------------------------------------------------------------------------------- @OnClick(R.id.btn_demo_timing_1) - public void Btn1_RunSingleTaskAfter2s() { + public void btn1_RunSingleTaskAfter2s() { _log(String.format("A1 [%s] --- BTN click", _getCurrentTimestamp())); Observable.timer(2, TimeUnit.SECONDS)// @@ -90,7 +91,7 @@ public void onNext(Long number) { } @OnClick(R.id.btn_demo_timing_2) - public void Btn2_RunTask_IntervalOf1s() { + public void btn2_RunTask_IntervalOf1s() { if (_subscription1 != null && !_subscription1.isUnsubscribed()) { _subscription1.unsubscribe(); _log(String.format("B2 [%s] XXX BTN KILLED", _getCurrentTimestamp())); @@ -120,7 +121,7 @@ public void onNext(Long number) { } @OnClick(R.id.btn_demo_timing_3) - public void Btn3_RunTask_IntervalOf1s_StartImmediately() { + public void btn3_RunTask_IntervalOf1s_StartImmediately() { if (_subscription2 != null && !_subscription2.isUnsubscribed()) { _subscription2.unsubscribe(); _log(String.format("C3 [%s] XXX BTN KILLED", _getCurrentTimestamp())); @@ -150,7 +151,7 @@ public void onNext(Long number) { } @OnClick(R.id.btn_demo_timing_4) - public void Btn4_RunTask5Times_IntervalOf3s() { + public void btn4_RunTask5Times_IntervalOf3s() { _log(String.format("D4 [%s] --- BTN click", _getCurrentTimestamp())); Observable// @@ -173,6 +174,42 @@ public void onNext(Long number) { }); } + @OnClick(R.id.btn_demo_timing_5) + public void btn5_RunTask5Times_IntervalOf3s() { + _log(String.format("D5 [%s] --- BTN click", _getCurrentTimestamp())); + + Observable.just("Do task A right away") + .doOnNext(new Action1() { + @Override + public void call(String input) { + _log(String.format("D5 %s [%s]", input, _getCurrentTimestamp())); + } + }) + .delay(1, TimeUnit.SECONDS) + .doOnNext(new Action1() { + @Override + public void call(String oldInput) { + _log(String.format("D5 %s [%s]", "Doing Task B after a delay", _getCurrentTimestamp())); + } + }) + .subscribe(new Observer() { + @Override + public void onCompleted() { + _log(String.format("D5 [%s] XXX COMPLETE", _getCurrentTimestamp())); + } + + @Override + public void onError(Throwable e) { + Timber.e(e, "something went wrong in TimingDemoFragment example"); + } + + @Override + public void onNext(String number) { + _log(String.format("D5 [%s] NEXT", _getCurrentTimestamp())); + } + }); + } + // ----------------------------------------------------------------------------------- // Method that help wiring up the example (irrelevant to RxJava) diff --git a/app/src/main/res/layout/fragment_demo_timing.xml b/app/src/main/res/layout/fragment_demo_timing.xml index 4129d5a7..e83be2be 100644 --- a/app/src/main/res/layout/fragment_demo_timing.xml +++ b/app/src/main/res/layout/fragment_demo_timing.xml @@ -25,7 +25,6 @@ android:gravity="left" android:text="@string/msg_demo_timing" android:layout_span="2" - /> @@ -72,6 +71,29 @@ android:text="BTN 4" /> + + + +