取数据先检查缓存的场景
取数据,首先检查内存是否有缓存
然后检查文件缓存中是否有
最后才从网络中取
前面任何一个条件满足,就不会执行后面的
<code class="language-Java hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Observable<String> memory = Observable.create(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Observable.OnSubscribe<String>() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">call</span>(Subscriber<? <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span> String> subscriber) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (memoryCache != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
subscriber.onNext(memoryCache);
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
subscriber.onCompleted();
}
}
});
Observable<String> disk = Observable.create(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Observable.OnSubscribe<String>() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">call</span>(Subscriber<? <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span> String> subscriber) {
String cachePref = rxPreferences.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cache"</span>).get();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!TextUtils.isEmpty(cachePref)) {
subscriber.onNext(cachePref);
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
subscriber.onCompleted();
}
}
});
Observable<String> network = Observable.just(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"network"</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//主要就是靠concat operator来实现</span>
Observable.concat(memory, disk, network)
.first()
.subscribeOn(Schedulers.newThread())
.subscribe(s -> {
memoryCache = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"memory"</span>;
System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"--------------subscribe: "</span> + s);
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>
界面需要等到多个接口并发取完数据,再更新
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">//拼接两个Observable的输出,不保证顺序,按照事件产生的顺序发送给订阅者
private void testMerge() {
Observable<String> observable1 = DemoUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createObservable</span>1()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribeOn</span>(Schedulers<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newThread</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
Observable<String> observable2 = DemoUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createObservable</span>2()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribeOn</span>(Schedulers<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newThread</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
Observable<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.merge</span>(observable1, observable2)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribeOn</span>(Schedulers<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newThread</span>())
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribe</span>(System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span>::println)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
一个接口的请求依赖另一个API请求返回的数据
举个例子,我们经常在需要登陆之后,根据拿到的token去获取消息列表。
这里用RxJava主要解决嵌套回调的问题,有一个专有名词叫Callback hell
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">NetworkService<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getToken</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"username"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"password"</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.flatMap</span>(s -> NetworkService<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMessage</span>(s))
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribe</span>(s -> {
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"message: "</span> + s)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
})<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
界面按钮需要防止连续点击的情况
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">RxView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.clicks</span>(findViewById(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.btn</span>_throttle))
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.throttleFirst</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, TimeUnit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SECONDS</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribe</span>(aVoid -> {
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"click"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
})<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
响应式的界面
比如勾选了某个checkbox,自动更新对应的preference
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">SharedPreferences preferences = PreferenceManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDefaultSharedPreferences</span>(this)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
RxSharedPreferences rxPreferences = RxSharedPreferences<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.create</span>(preferences)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
Preference<Boolean> checked = rxPreferences<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getBoolean</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"checked"</span>, true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
CheckBox checkBox = (CheckBox) findViewById(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cb</span>_test)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
RxCompoundButton<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.checkedChanges</span>(checkBox)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribe</span>(checked<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.asAction</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
复杂的数据变换
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">Observable<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.just</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"2"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"2"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"3"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"4"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"5"</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.map</span>(Integer::parseInt)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.filter</span>(s -> s > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.distinct</span>()
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.take</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reduce</span>((integer, integer2) -> integer<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.intValue</span>() + integer2<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.intValue</span>())
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.subscribe</span>(System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span>::println)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;//9</span></code>