Skip to content

Commit 958214c

Browse files
author
Kaushik Gopal
committed
feat: add debounce to subject
1 parent c852573 commit 958214c

File tree

6 files changed

+45
-40
lines changed

6 files changed

+45
-40
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ protected void onCreate(Bundle savedInstanceState) {
2020
getSupportFragmentManager().beginTransaction()
2121
.addToBackStack(this.toString())
2222
// .replace(R.id.activity_main, new MainFragment(), this.toString())
23-
.replace(R.id.activity_main, new SubjectSearchEmitterFragment(), this.toString())
23+
.replace(R.id.activity_main, new SubjectDebounceSearchEmitterFragment(), this.toString())
2424
.commit();
2525
}
2626
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ public void demoBuffer() {
4646
.commit();
4747
}
4848

49-
@OnClick(R.id.btn_demo_subject)
49+
@OnClick(R.id.btn_demo_subject_debounce)
5050
public void demoThrottling() {
5151
getActivity().getSupportFragmentManager()
5252
.beginTransaction()
5353
.addToBackStack(this.toString())
5454
.replace(R.id.activity_main,
55-
new SubjectSearchEmitterFragment(),
55+
new SubjectDebounceSearchEmitterFragment(),
5656
this.toString())
5757
.commit();
5858
}

app/src/main/java/com/morihacky/android/rxjava/SubjectSearchEmitterFragment.java renamed to app/src/main/java/com/morihacky/android/rxjava/SubjectDebounceSearchEmitterFragment.java

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.util.ArrayList;
1818
import java.util.List;
19+
import java.util.concurrent.TimeUnit;
1920

2021
import butterknife.ButterKnife;
2122
import butterknife.InjectView;
@@ -43,12 +44,12 @@
4344
* (unlike the way it's done in {@link com.morihacky.android.rxjava.ConcurrencyWithSchedulersDemoFragment#startLongOperation()})
4445
* where we create the subscription on every single event change (OnClick or OnTextchanged) which is
4546
*
46-
* ? wasteful (not really since we anyway unsubscribe at the end).
47-
* less-elegant (as a concept for sure, but not for simplicity vs. the 3 step basic subscription creation)
48-
* ? doesn't allow us to debounce/throttle/sample
49-
*
47+
* wasteful! : not really since we anyway unsubscribe in OnDestroyView)
48+
* less-elegant : as a concept for sure
49+
* simpler actually : adds one more step in the 3 step subscription process, where we create emitter, and then send observables to that emitter)
50+
* incapable of debounce : this is the primary reason, since creating new observable everytime in subscription disregards debounce on subsequent calls
5051
*/
51-
public class SubjectSearchEmitterFragment
52+
public class SubjectDebounceSearchEmitterFragment
5253
extends Fragment {
5354

5455
@InjectView(R.id.list_threading_log) ListView _logsList;
@@ -65,34 +66,11 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
6566
_setupLogger();
6667

6768
_searchTextEmitterSubject = PublishSubject.create();
68-
_subscription = AndroidObservable.bindFragment(SubjectSearchEmitterFragment.this,
69+
_subscription = AndroidObservable.bindFragment(SubjectDebounceSearchEmitterFragment.this,
6970
Observable.switchOnNext(_searchTextEmitterSubject))
70-
.subscribeOn(Schedulers.io())
71+
.debounce(400, TimeUnit.MILLISECONDS, Schedulers.io())
7172
.observeOn(AndroidSchedulers.mainThread())
7273
.subscribe(_getSearchObserver());
73-
74-
// .debounce(400, TimeUnit.MILLISECONDS, Schedulers.io())
75-
}
76-
77-
@OnTextChanged(R.id.input_txt_subject)
78-
public void onTextEntered(CharSequence charsEntered) {
79-
Timber.d("---------- text entered %s", charsEntered);
80-
_searchTextEmitterSubject.onNext(_getASearchObservableFor(charsEntered.toString()));
81-
}
82-
83-
// -----------------------------------------------------------------------------------
84-
// Main Rx entities
85-
86-
private Observable<String> _getASearchObservableFor(final String searchText) {
87-
return Observable.create(new Observable.OnSubscribe<String>() {
88-
89-
90-
@Override
91-
public void call(Subscriber<? super String> subscriber) {
92-
subscriber.onNext(searchText);
93-
subscriber.onCompleted();
94-
}
95-
});
9674
}
9775

9876
private Observer<String> _getSearchObserver() {
@@ -112,12 +90,39 @@ public void onError(Throwable e) {
11290

11391
@Override
11492
public void onNext(String searchText) {
115-
Timber.d("--------- onNext");
116-
_log(String.format("You searched for %s", searchText));
93+
_log(String.format("onNext You searched for %s", searchText));
11794
}
11895
};
11996
}
12097

98+
@OnTextChanged(R.id.input_txt_subject_debounce)
99+
public void onTextEntered(CharSequence charsEntered) {
100+
Timber.d("---------- text entered %s", charsEntered);
101+
_searchTextEmitterSubject.onNext(_getASearchObservableFor(charsEntered.toString()));
102+
}
103+
104+
// -----------------------------------------------------------------------------------
105+
// Main Rx entities
106+
107+
/**
108+
* @param searchText search text entered onTextChange
109+
*
110+
* @return a new observable which searches for text searchText, explicitly say you want subscription to be done on a a non-UI thread, otherwise it'll default to the main thread.
111+
*/
112+
private Observable<String> _getASearchObservableFor(final String searchText) {
113+
return Observable.create(new Observable.OnSubscribe<String>() {
114+
115+
116+
@Override
117+
public void call(Subscriber<? super String> subscriber) {
118+
119+
Timber.d("----------- inside the search observable");
120+
subscriber.onNext(searchText);
121+
subscriber.onCompleted();
122+
}
123+
}).subscribeOn(Schedulers.io());
124+
}
125+
121126
@Override
122127
public void onDestroy() {
123128
super.onDestroy();
@@ -131,7 +136,7 @@ public void onDestroy() {
131136
public View onCreateView(LayoutInflater inflater,
132137
@Nullable ViewGroup container,
133138
@Nullable Bundle savedInstanceState) {
134-
View layout = inflater.inflate(R.layout.fragment_subject, container, false);
139+
View layout = inflater.inflate(R.layout.fragment_subject_debounce, container, false);
135140
ButterKnife.inject(this, layout);
136141
return layout;
137142
}

app/src/main/res/layout/fragment_main.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
android:text="@string/btn_demo_buffer"/>
2424

2525
<Button
26-
android:id="@+id/btn_demo_subject"
26+
android:id="@+id/btn_demo_subject_debounce"
2727
android:layout_height="wrap_content"
2828
android:layout_width="wrap_content"
29-
android:text="@string/btn_demo_subject"/>
29+
android:text="@string/btn_demo_subject_debounce"/>
3030

3131
</LinearLayout>

app/src/main/res/layout/fragment_subject.xml renamed to app/src/main/res/layout/fragment_subject_debounce.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
android:text="@string/msg_demo_subject"/>
1515

1616
<EditText
17-
android:id="@+id/input_txt_subject"
17+
android:id="@+id/input_txt_subject_debounce"
1818
android:layout_height="wrap_content"
1919
android:layout_width="match_parent"
2020
android:textSize="16sp"

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
<string name="btn_demo_schedulers">bg work (schedulers &amp; concurrency)</string>
1313
<string name="btn_demo_buffer">accumulate calls (buffer)</string>
14-
<string name="btn_demo_subject">instant search (subject throttling?)</string>
14+
<string name="btn_demo_subject_debounce">search text listener(subject debouncing)</string>
1515

1616
</resources>

0 commit comments

Comments
 (0)