Skip to content

Commit f8f59b5

Browse files
author
Venkatesh Burgula
committed
Resolve Conflicts
2 parents bd7c036 + e83b02e commit f8f59b5

File tree

79 files changed

+3933
-3369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+3933
-3369
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ buck-out/
2222
.buckd/
2323

2424
# Intellij project files
25+
.idea/
2526
.idea/libraries
2627
.idea/.name
2728
.idea/compiler.xml

README.md

+34-17
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,24 @@ I've also been giving talks about Learning Rx using many of the examples listed
1010

1111
## Examples:
1212

13-
1. [Background work & concurrency (using Schedulers)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#1-background-work--concurrency-using-schedulers)
14-
2. [Accumulate calls (using buffer)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#2-accumulate-calls-using-buffer)
15-
3. [Instant/Auto searching text listeners (using Subjects & debounce)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#3-instantauto-searching-text-listeners-using-subjects--debounce)
16-
4. [Networking with Retrofit & RxJava (using zip, flatmap)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#4-networking-with-retrofit--rxjava-using-zip-flatmap)
17-
5. [Two-way data binding for TextViews (using PublishSubject)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#5-two-way-data-binding-for-textviews-using-publishsubject)
18-
6. [Simple and Advanced polling (using interval and repeatWhen)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#6-simple-and-advanced-polling-using-interval-and-repeatwhen)
19-
7. [Simple and Advanced exponential backoff (using delay and retryWhen)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#7-simple-and-advanced-exponential-backoff-using-delay-and-retrywhen)
20-
8. [Form validation (using combineLatest)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#8-form-validation-using-combinelatest)
21-
9. [Pseudo caching : retrieve data first from a cache, then a network call (using concat, concatEager, merge or publish)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#9-pseudo-caching--retrieve-data-first-from-a-cache-then-a-network-call-using-concat-concateager-merge-or-publish)
22-
10. [Simple timing demos (using timer, interval or delay)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#10-simple-timing-demos-using-timer-interval-and-delay)
23-
11. [RxBus : event bus using RxJava (using RxRelay (never terminating Subjects) and debouncedBuffer)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#11-rxbus--event-bus-using-rxjava-using-rxrelay-never-terminating-subjects-and-debouncedbuffer)
24-
12. [Persist data on Activity rotations (using Subjects and retained Fragments)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#12-persist-data-on-activity-rotations-using-subjects-and-retained-fragments)
25-
13. [Networking with Volley](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#13-networking-with-volley)
26-
14. [Pagination with Rx (using Subjects)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#14-pagination-with-rx-using-subjects)
27-
15. [Orchestrating Observable: make parallel network calls, then combine the result into a single data point (using flatmap & zip)](https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#15-orchestrating-observable-make-parallel-network-calls-then-combine-the-result-into-a-single-data-point-using-flatmap--zip)
28-
16. [Simple Timeout example (using timeout)]()
13+
1. [Background work & concurrency (using Schedulers)](#1-background-work--concurrency-using-schedulers)
14+
2. [Accumulate calls (using buffer)](#2-accumulate-calls-using-buffer)
15+
3. [Instant/Auto searching text listeners (using Subjects & debounce)](#3-instantauto-searching-text-listeners-using-subjects--debounce)
16+
4. [Networking with Retrofit & RxJava (using zip, flatmap)](#4-networking-with-retrofit--rxjava-using-zip-flatmap)
17+
5. [Two-way data binding for TextViews (using PublishSubject)](#5-two-way-data-binding-for-textviews-using-publishsubject)
18+
6. [Simple and Advanced polling (using interval and repeatWhen)](#6-simple-and-advanced-polling-using-interval-and-repeatwhen)
19+
7. [Simple and Advanced exponential backoff (using delay and retryWhen)](#7-simple-and-advanced-exponential-backoff-using-delay-and-retrywhen)
20+
8. [Form validation (using combineLatest)](#8-form-validation-using-combinelatest)
21+
9. [Pseudo caching : retrieve data first from a cache, then a network call (using concat, concatEager, merge or publish)](#9-pseudo-caching--retrieve-data-first-from-a-cache-then-a-network-call-using-concat-concateager-merge-or-publish)
22+
10. [Simple timing demos (using timer, interval or delay)](#10-simple-timing-demos-using-timer-interval-and-delay)
23+
11. [RxBus : event bus using RxJava (using RxRelay (never terminating Subjects) and debouncedBuffer)](#11-rxbus--event-bus-using-rxjava-using-rxrelay-never-terminating-subjects-and-debouncedbuffer)
24+
12. [Persist data on Activity rotations (using Subjects and retained Fragments)](#12-persist-data-on-activity-rotations-using-subjects-and-retained-fragments)
25+
13. [Networking with Volley](#13-networking-with-volley)
26+
14. [Pagination with Rx (using Subjects)](#14-pagination-with-rx-using-subjects)
27+
15. [Orchestrating Observable: make parallel network calls, then combine the result into a single data point (using flatmap & zip)](#15-orchestrating-observable-make-parallel-network-calls-then-combine-the-result-into-a-single-data-point-using-flatmap--zip)
28+
16. [Simple Timeout example (using timeout)](#16-simple-timeout-example-using-timeout)
29+
17. [Setup and teardown resources (using `using`)](#17-setup-and-teardown-resources-using-using)
30+
18. [Multicast playground](#18-multicast-playground)
2931

3032
## Description
3133

@@ -100,6 +102,7 @@ We simulate this behaviour using RxJava with the [`retryWhen` operator](http://r
100102

101103
* http://stackoverflow.com/a/25292833/159825
102104
* Another excellent implementation via @[sddamico](https://github.com/sddamico) : https://gist.github.com/sddamico/c45d7cdabc41e663bea1
105+
* This one includes support for jittering, by @[leandrofavarin](https://github.com/leandrofavarin) : http://leandrofavarin.com/exponential-backoff-rxjava-operator-with-jitter
103106

104107
Also look at the [Polling example](https://github.com/kaushikgopal/RxJava-Android-Samples#polling-with-schedulers) where we use a very similar Exponential backoff mechanism.
105108

@@ -160,7 +163,7 @@ Cases demonstrated here:
160163
4. run a task constantly every 3s, but after running it 5 times, terminate automatically
161164
5. run a task A, pause for sometime, then execute Task B, then terminate
162165

163-
### 11. RxBus : event bus using RxJava (using RxRelay (never terminating Subjects) and debouncedBuffer)
166+
### 11. RxBus : event bus using RxJava (using RxRelay (never terminating Subjects) and debouncedBuffer)
164167

165168
There are accompanying blog posts that do a much better job of explaining the details on this demo:
166169

@@ -221,6 +224,20 @@ This is a simple example demonstrating the use of the `.timeout` operator. Butto
221224

222225
Notice how we can provide a custom Observable that indicates how to react under a timeout Exception.
223226

227+
### 17. Setup and teardown resources (using `using`)
228+
229+
The [operator `using`](http://reactivex.io/documentation/operators/using.html) is relatively less known and notoriously hard to Google. It's a beautiful API that helps to setup a (costly) resource, use it and then dispose off in a clean way.
230+
231+
The nice thing about this operator is that it provides a mechansim to use potentially costly resources in a tightly scoped manner. using -> setup, use and dispose. Think DB connections (like Realm instances), socket connections, thread locks etc.
232+
233+
### 18. Multicast Playground
234+
235+
Multicasting in Rx is like a dark art. Not too many folks know how to pull it off without concern. This example condiers two subscribers (in the forms of buttons) and allows you to add/remove subscribers at different points of time and see how the different operators behave under those circumstances.
236+
237+
The source observale is a timer (`interval`) observable and the reason this was chosen was to intentionally pick a non-terminating observable, so you can test/confirm if your multicast experiment will leak.
238+
239+
_I also gave a talk about [Multicasting in detail at 360|Andev](https://speakerdeck.com/kaushikgopal/rx-by-example-volume-3-the-multicast-edition). If you have the inclination and time, I highly suggest watching that talk first (specifically the Multicast operator permutation segment) and then messing around with the example here._
240+
224241
## Rx 2.x
225242

226243
All the examples here have been migrated to use RxJava 2.X.

app/build.gradle

+27-23
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ buildscript {
44
jcenter()
55
}
66
dependencies {
7-
classpath 'me.tatarka:gradle-retrolambda:3.2.5'
8-
// can be removed with android-gradle plugin is upgraded to 2.2
9-
// https://twitter.com/JakeWharton/status/760836175586267136
10-
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
7+
classpath 'me.tatarka:gradle-retrolambda:3.6.0'
8+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
119
}
1210

1311
// Exclude the lombok version that the android plugin depends on.
@@ -16,73 +14,79 @@ buildscript {
1614

1715
apply plugin: 'com.android.application'
1816
apply plugin: 'me.tatarka.retrolambda'
19-
20-
ext {
21-
okhttpVersion = "3.0.1"
22-
retrofitVersion = "2.0.0"
23-
sdkVersion = 24
24-
supportLibVersion = "24.2.1"
25-
}
17+
apply plugin: 'com.f2prateek.javafmt'
18+
apply plugin: 'kotlin-android'
2619

2720
dependencies {
21+
compile 'com.android.support:multidex:1.0.1'
2822
compile "com.android.support:support-v13:${supportLibVersion}"
2923
compile "com.android.support:appcompat-v7:${supportLibVersion}"
3024
compile "com.android.support:recyclerview-v7:${supportLibVersion}"
3125

3226
compile 'com.github.kaushikgopal:CoreTextUtils:c703fa12b6'
33-
compile 'com.jakewharton:butterknife:7.0.1'
34-
compile 'com.jakewharton.timber:timber:2.4.2'
27+
compile "com.jakewharton:butterknife:${butterKnifeVersion}"
28+
kapt "com.jakewharton:butterknife-compiler:${butterKnifeVersion}"
29+
compile 'com.jakewharton.timber:timber:4.5.1'
3530
compile "com.squareup.retrofit2:retrofit:${retrofitVersion}"
3631
compile "com.squareup.retrofit2:converter-gson:${retrofitVersion}"
3732
compile "com.squareup.okhttp3:okhttp:${okhttpVersion}"
3833
compile "com.squareup.okhttp3:okhttp-urlconnection:${okhttpVersion}"
3934
compile 'com.mcxiaoke.volley:library:1.0.19'
4035

36+
compile "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"
37+
compile "com.nhaarman:mockito-kotlin:${mockitoKotlinVersion}"
38+
39+
compile "android.arch.lifecycle:runtime:${archComponentsVersion}"
40+
compile "android.arch.lifecycle:extensions:${archComponentsVersion}"
41+
kapt "android.arch.lifecycle:compiler:${archComponentsVersion}"
42+
4143
// ----------------------------------
4244
// Rx dependencies
4345

44-
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
46+
compile 'io.reactivex.rxjava2:rxjava:2.0.7'
4547

4648
// Because RxAndroid releases are few and far between, it is recommended you also
4749
// explicitly depend on RxJava's latest version for bug fixes and new features.
4850
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
4951

50-
// libs like rxbinding + rxjava-math haven't been ported to RxJava 2.x yet, so this helps
51-
compile "com.github.akarnokd:rxjava2-interop:0.6.1"
52-
53-
compile 'io.reactivex:rxjava-math:1.0.0'
52+
compile 'com.jakewharton.rx:replaying-share-kotlin:2.0.0'
53+
compile "com.github.akarnokd:rxjava2-extensions:0.16.0"
5454
compile 'com.jakewharton.rxrelay2:rxrelay:2.0.0'
55-
compile 'com.jakewharton.rxbinding:rxbinding:0.2.0'
55+
56+
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
5657
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
5758

5859
// ----------------------------------
5960

60-
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
61-
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
61+
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
62+
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
6263
}
6364

6465
android {
6566
compileSdkVersion sdkVersion
66-
buildToolsVersion '23.0.3'
67+
buildToolsVersion buildToolsVrs
6768

6869
defaultConfig {
6970
applicationId "com.morihacky.android.rxjava"
7071
minSdkVersion 15
7172
targetSdkVersion sdkVersion
7273
versionCode 2
7374
versionName "1.2"
75+
multiDexEnabled true
7476
}
7577
buildTypes {
7678
release {
7779
minifyEnabled true
7880
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
7981
}
8082
}
83+
sourceSets {
84+
main.java.srcDirs += 'src/main/kotlin'
85+
}
8186
compileOptions {
8287
sourceCompatibility JavaVersion.VERSION_1_8
8388
targetCompatibility JavaVersion.VERSION_1_8
8489
}
85-
8690
packagingOptions {
8791
pickFirst 'META-INF/rxjava.properties'
8892
}

app/src/main/java/com/morihacky/android/rxjava/MainActivity.java

+38-40
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,58 @@
22

33
import android.os.Bundle;
44
import android.support.v4.app.Fragment;
5-
import android.support.v4.app.FragmentActivity;
5+
import android.support.v7.app.AppCompatActivity;
66
import com.morihacky.android.rxjava.fragments.MainFragment;
77
import com.morihacky.android.rxjava.fragments.RotationPersist1WorkerFragment;
88
import com.morihacky.android.rxjava.fragments.RotationPersist2WorkerFragment;
99
import com.morihacky.android.rxjava.rxbus.RxBus;
1010

11-
public class MainActivity
12-
extends FragmentActivity {
11+
public class MainActivity extends AppCompatActivity {
1312

14-
private RxBus _rxBus = null;
13+
private RxBus _rxBus = null;
1514

16-
@Override
17-
public void onBackPressed() {
18-
super.onBackPressed();
19-
_removeWorkerFragments();
20-
}
15+
@Override
16+
public void onBackPressed() {
17+
super.onBackPressed();
18+
_removeWorkerFragments();
19+
}
2120

22-
@Override
23-
protected void onCreate(Bundle savedInstanceState) {
24-
super.onCreate(savedInstanceState);
21+
@Override
22+
protected void onCreate(Bundle savedInstanceState) {
23+
super.onCreate(savedInstanceState);
2524

26-
if (savedInstanceState == null) {
27-
getSupportFragmentManager().beginTransaction()
28-
.replace(android.R.id.content, new MainFragment(), this.toString())
29-
.commit();
30-
}
25+
if (savedInstanceState == null) {
26+
getSupportFragmentManager()
27+
.beginTransaction()
28+
.replace(android.R.id.content, new MainFragment(), this.toString())
29+
.commit();
3130
}
31+
}
3232

33-
// This is better done with a DI Library like Dagger
34-
public RxBus getRxBusSingleton() {
35-
if (_rxBus == null) {
36-
_rxBus = new RxBus();
37-
}
38-
39-
return _rxBus;
33+
// This is better done with a DI Library like Dagger
34+
public RxBus getRxBusSingleton() {
35+
if (_rxBus == null) {
36+
_rxBus = new RxBus();
4037
}
4138

42-
private void _removeWorkerFragments() {
43-
Fragment frag = getSupportFragmentManager().findFragmentByTag(RotationPersist1WorkerFragment.class.getName());
39+
return _rxBus;
40+
}
4441

45-
if (frag != null) {
46-
getSupportFragmentManager()
47-
.beginTransaction()
48-
.remove(frag)
49-
.commit();
50-
}
42+
private void _removeWorkerFragments() {
43+
Fragment frag =
44+
getSupportFragmentManager()
45+
.findFragmentByTag(RotationPersist1WorkerFragment.class.getName());
46+
47+
if (frag != null) {
48+
getSupportFragmentManager().beginTransaction().remove(frag).commit();
49+
}
5150

52-
frag = getSupportFragmentManager().findFragmentByTag(RotationPersist2WorkerFragment.class.getName());
51+
frag =
52+
getSupportFragmentManager()
53+
.findFragmentByTag(RotationPersist2WorkerFragment.class.getName());
5354

54-
if (frag != null) {
55-
getSupportFragmentManager()
56-
.beginTransaction()
57-
.remove(frag)
58-
.commit();
59-
}
55+
if (frag != null) {
56+
getSupportFragmentManager().beginTransaction().remove(frag).commit();
6057
}
61-
}
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,43 @@
11
package com.morihacky.android.rxjava;
22

3-
import android.app.Application;
3+
import android.support.multidex.MultiDexApplication;
44
import com.morihacky.android.rxjava.volley.MyVolley;
55
import com.squareup.leakcanary.LeakCanary;
66
import com.squareup.leakcanary.RefWatcher;
77
import timber.log.Timber;
88

9-
public class MyApp
10-
extends Application {
9+
public class MyApp extends MultiDexApplication {
1110

12-
private static MyApp _instance;
13-
private RefWatcher _refWatcher;
11+
private static MyApp _instance;
12+
private RefWatcher _refWatcher;
1413

15-
public static MyApp get() {
16-
return _instance;
17-
}
14+
public static MyApp get() {
15+
return _instance;
16+
}
1817

19-
public static RefWatcher getRefWatcher() {
20-
return MyApp.get()._refWatcher;
21-
}
18+
public static RefWatcher getRefWatcher() {
19+
return MyApp.get()._refWatcher;
20+
}
2221

23-
@Override
24-
public void onCreate() {
25-
super.onCreate();
22+
@Override
23+
public void onCreate() {
24+
super.onCreate();
2625

27-
_instance = (MyApp) getApplicationContext();
28-
_refWatcher = LeakCanary.install(this);
26+
if (LeakCanary.isInAnalyzerProcess(this)) {
27+
// This process is dedicated to LeakCanary for heap analysis.
28+
// You should not init your app in this process.
29+
return;
30+
}
2931

30-
// for better RxJava debugging
31-
//RxJavaHooks.enableAssemblyTracking();
32+
_instance = (MyApp) getApplicationContext();
33+
_refWatcher = LeakCanary.install(this);
3234

33-
// Initialize Volley
34-
MyVolley.init(this);
35+
// for better RxJava debugging
36+
//RxJavaHooks.enableAssemblyTracking();
3537

36-
Timber.plant(new Timber.DebugTree());
37-
}
38+
// Initialize Volley
39+
MyVolley.init(this);
40+
41+
Timber.plant(new Timber.DebugTree());
42+
}
3843
}

app/src/main/java/com/morihacky/android/rxjava/fragments/BaseFragment.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
import com.morihacky.android.rxjava.MyApp;
55
import com.squareup.leakcanary.RefWatcher;
66

7-
public class BaseFragment
8-
extends Fragment {
7+
public class BaseFragment extends Fragment {
98

10-
@Override
11-
public void onDestroy() {
12-
super.onDestroy();
13-
RefWatcher refWatcher = MyApp.getRefWatcher();
14-
refWatcher.watch(this);
15-
}
9+
@Override
10+
public void onDestroy() {
11+
super.onDestroy();
12+
RefWatcher refWatcher = MyApp.getRefWatcher();
13+
refWatcher.watch(this);
14+
}
1615
}

0 commit comments

Comments
 (0)