听说如今流行的开发模式是 Retrofit+RxJava+MVP+ButterKnifephp
若是想要简单学习ButterKnife、MVP模式,能够参考我之前的例子
使用butterknife注解框架
Android—MVP设计模式高级(三)java
今天我就简单来学习下RxJava的相关知识
之前我也只是据说过RxJava,RxJava这个究竟是什么东西呢?
呵呵,它实际上是一个库,因此咱们使用里面的方法,得须要下载库,因此咱们须要在AS中进行配置react
1.RxJava 地址以及添加android
github地址:
https://github.com/ReactiveX/RxJava
或者
https://github.com/ReactiveX/RxAndroidgit
依赖库添加:
compile ‘io.reactivex:rxjava:1.1.6’
或者
compile ‘io.reactivex:rxandroid:1.2.1’github
2.RxJava是什么类型的库?它的原理是什么?数据库
RxJava 在 GitHub 主页上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,归纳得很是精准。编程
Rx:函数响应式编程,也许这个词对你我都很只可意会,不可言传,先抛开Rx不说,咱们接触到的相似的这样的思路,大概有接口回调、Handler通信、广播通信、还有一个开源的EventBus、以及ContentPorivider里面的观察者模式、AsyncTask 咱们朦胧中也许就大概了解RxJava是怎么个东西了。设计模式
RxJava 的异步实现,是经过一种扩展的观察者模式来实现的。
至于观察者我就拿ContentProvider来讲吧,好比咱们在一个ContentProvider中有一个insert方法,插入完毕后,去通知某个监听该URI变化的界面api
<code class="hljs avrasm has-numbering">getContext()<span class="hljs-preprocessor">.getContentResolver</span>()<span class="hljs-preprocessor">.notifyChange</span>(URI, null)<span class="hljs-comment">;</span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
好比在MainActivity中去registerContentObserver注册一个内容观察者
<code class="hljs java has-numbering"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Uri URI = Uri .parse(<span class="hljs-string">"content://com.example.contentprovider.MyContentProvider/student"</span>); contentResolver.registerContentObserver(uri, <span class="hljs-keyword">true</span>, observer);</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>
<code class="hljs java has-numbering"> <span class="hljs-keyword">private</span> ContentObserver observer = <span class="hljs-keyword">new</span> ContentObserver(<span class="hljs-keyword">null</span>) { <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onChange</span>(<span class="hljs-keyword">boolean</span> selfChange) { <span class="hljs-comment">// 说明数据有改变,从新查询一直全部记录 </span> Uri uri = Uri.parse(<span class="hljs-string">"content://com.example.contentprovider.MyContentProvider/student"</span>); Cursor cursor = contentResolver.query(uri, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>); Log.e(<span class="hljs-string">"TAG"</span>, <span class="hljs-string">"onChange() count="</span> + cursor.getCount()); }; }; </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul>
那么对于RxJava 的观察者模式呢?
RxJava 有四个基本概念:Observable (被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。
对比ContentProvider,RxJava里面的被观察者就是某个Uri(也就是某个数据库),观察者就是某个界面(好比MainActivity),订阅就是registerContentObserver,事件就是insert方法
Rxjava本质主要就是异步任务 外层构建了一个观察者的设计模式 它更简洁 咱们调用api方法 几乎看不到 方法里面的 分线程数据操做 它只是利用了 一种观察者的设计模式 来进行 主分线程的通信 来进行响应操做
咱们来看看RxJava的察者模式流程交互图:
与传统观察者模式不一样, RxJava 的事件回调方法除了普通事件 onNext() (至关于 insert)以外,还定义了两个特殊的事件:onCompleted() 和 onError()。
咱们来看下Observable是如何定义的?
<code class="hljs avrasm has-numbering"> Observable<span class="hljs-preprocessor">.create</span>(new Observable<span class="hljs-preprocessor">.OnSubscribe</span><String>() { @Override public void <span class="hljs-keyword">call</span>(Subscriber<? super String> subscriber) { Log<span class="hljs-preprocessor">.d</span>(TAG, <span class="hljs-string">"call: threadId:"</span> + Thread<span class="hljs-preprocessor">.currentThread</span>()<span class="hljs-preprocessor">.getId</span>())<span class="hljs-comment">;</span> subscriber<span class="hljs-preprocessor">.onStart</span>()<span class="hljs-comment">;</span> subscriber<span class="hljs-preprocessor">.onNext</span>(<span class="hljs-string">"Hello World!"</span>)<span class="hljs-comment">;</span> subscriber<span class="hljs-preprocessor">.onCompleted</span>()<span class="hljs-comment">;</span> } })</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
咱们看看create源码里面作了什么?
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <T> Observable<T> <span class="hljs-title">create</span>(OnSubscribe<T> f) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Observable<T>(hook.onCreate(f)); }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>
能够看到,这里传入了一个 OnSubscribe 对象做为参数。OnSubscribe 会被存储在返回的 Observable 对象中,当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发(对于上面的代码,就是观察者Subscriber 将会被调用一次 onNext() 和一次 onCompleted())。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。
而后在看Observer中作了什么操做?
<code class="hljs lasso has-numbering">subscribe(<span class="hljs-literal">new</span> Observer<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onCompleted() { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onCompleted: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onError(Throwable e) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>e(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onError: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onNext(<span class="hljs-built_in">String</span> s) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onNext: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onNext: s = "</span> <span class="hljs-subst">+</span> s); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul>
onCompleted(): 事件队列完结。RxJava 不只把每一个事件单独处理,还会把它们看作一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,须要触发 onCompleted() 方法做为标志。
onError(): 事件队列异常。在事件处理过程当中出异常时,onError() 会被触发,同时队列自动终止,不容许再有事件发出。
在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,而且是事件序列中的最后一个。须要注意的是,onCompleted() 和 onError() 两者也是互斥的,即在队列中调用了其中一个,就不该该再调用另外一个。
接下来咱们将所有的代码贴出来,看看Log日志打印:
同步方式
<code class="hljs java has-numbering"><span class="hljs-keyword">package</span> com.example.administrator.myapplication; <span class="hljs-keyword">import</span> android.app.Activity; <span class="hljs-keyword">import</span> android.os.Bundle; <span class="hljs-keyword">import</span> android.util.Log; <span class="hljs-keyword">import</span> rx.Observable; <span class="hljs-keyword">import</span> rx.Observer; <span class="hljs-keyword">import</span> rx.Subscriber; <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span> <span class="hljs-keyword">private</span> String TAG = <span class="hljs-string">"MainActivity"</span>; <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Observable.create(<span class="hljs-keyword">new</span> Observable.OnSubscribe<String>() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">call</span>(Subscriber<? <span class="hljs-keyword">super</span> String> subscriber) { Log.d(TAG, <span class="hljs-string">"call: threadId:"</span> + Thread.currentThread().getId()); subscriber.onStart(); subscriber.onNext(<span class="hljs-string">"Hello World!"</span>); subscriber.onCompleted(); } }) .subscribe(<span class="hljs-keyword">new</span> Observer<String>() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCompleted</span>() { Log.d(TAG, <span class="hljs-string">"onCompleted: threadId:"</span> + Thread.currentThread().getId()); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onError</span>(Throwable e) { Log.e(TAG, <span class="hljs-string">"onError: threadId:"</span> + Thread.currentThread().getId()); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onNext</span>(String s) { Log.d(TAG, <span class="hljs-string">"onNext: threadId:"</span> + Thread.currentThread().getId()); Log.i(TAG, <span class="hljs-string">"onNext: s = "</span> + s); } }); } } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li></ul>
<code class="hljs http has-numbering"><span class="hljs-attribute">call</span>: <span class="hljs-string">threadId:1</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">threadId:1</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">s = Hello World!</span> <span class="hljs-attribute">onCompleted</span>: <span class="hljs-string">threadId:1</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
从上能够看出,事件的处理和结果的接收都是在同一个线程里面处理的。可是,Rxjava的意义何在,异步呢?别急,看如下代码的处理,你就会发现了,异步原来是这么的简单。
异步方式
咱们将上面的代码稍微改下,增长2行代码
<code class="hljs lasso has-numbering"> Observable<span class="hljs-built_in">.</span>create(<span class="hljs-literal">new</span> Observable<span class="hljs-built_in">.</span>OnSubscribe<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> call(Subscriber<span class="hljs-subst"><?</span> super <span class="hljs-built_in">String</span><span class="hljs-subst">></span> subscriber) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); subscriber<span class="hljs-built_in">.</span>onStart(); subscriber<span class="hljs-built_in">.</span>onNext(<span class="hljs-string">"Hello World!"</span>); subscriber<span class="hljs-built_in">.</span>onCompleted(); } }) <span class="hljs-built_in">.</span>subscribeOn(Schedulers<span class="hljs-built_in">.</span>io()) <span class="hljs-built_in">.</span>observeOn(AndroidSchedulers<span class="hljs-built_in">.</span>mainThread()) <span class="hljs-built_in">.</span>subscribe(<span class="hljs-literal">new</span> Observer<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onCompleted() { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onCompleted: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onError(Throwable e) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>e(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onError: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onNext(<span class="hljs-built_in">String</span> s) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onNext: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onNext: s = "</span> <span class="hljs-subst">+</span> s); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul>
咱们添上以下2行代码
<code class="hljs avrasm has-numbering"><span class="hljs-preprocessor">.subscribeOn</span>(Schedulers<span class="hljs-preprocessor">.io</span>()) <span class="hljs-preprocessor">.observeOn</span>(AndroidSchedulers<span class="hljs-preprocessor">.mainThread</span>())</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
咱们看下Log输出
<code class="hljs mathematica has-numbering"><span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">07</span>:<span class="hljs-number">20</span>:<span class="hljs-number">18.101</span> <span class="hljs-number">22734</span>-<span class="hljs-number">22734</span>/? <span class="hljs-keyword">I</span>/MainActivity: testFunction: threadId:<span class="hljs-number">1</span> <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">07</span>:<span class="hljs-number">20</span>:<span class="hljs-number">18.123</span> <span class="hljs-number">22734</span>-<span class="hljs-number">22755</span>/? <span class="hljs-keyword">D</span>/MainActivity: call: threadId:<span class="hljs-number">180</span> <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">07</span>:<span class="hljs-number">20</span>:<span class="hljs-number">18.142</span> <span class="hljs-number">22734</span>-<span class="hljs-number">22734</span>/? <span class="hljs-keyword">D</span>/MainActivity: onNext: threadId:<span class="hljs-number">1</span> <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">07</span>:<span class="hljs-number">20</span>:<span class="hljs-number">18.142</span> <span class="hljs-number">22734</span>-<span class="hljs-number">22734</span>/? <span class="hljs-keyword">I</span>/MainActivity: onNext: s = Hello World! <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">07</span>:<span class="hljs-number">20</span>:<span class="hljs-number">18.143</span> <span class="hljs-number">22734</span>-<span class="hljs-number">22734</span>/? <span class="hljs-keyword">D</span>/MainActivity: onCompleted: threadId:<span class="hljs-number">1</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
看见了没,第二行log日志threadId与其它的threadId很明显的不同啊,说明咱们在处理事件的时候,发生在了一个新的线程里面,而结果的接收,仍是在主线程里面操做的。怎么样,只要添加两句话,异步立马就实现了,异步处理耗时操做,就是这么easy。
咱们简单看下源码
<code class="hljs java has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> Observable<T> <span class="hljs-title">subscribeOn</span>(Scheduler scheduler) { <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span> <span class="hljs-keyword">instanceof</span> ScalarSynchronousObservable) { <span class="hljs-keyword">return</span> ((ScalarSynchronousObservable<T>)<span class="hljs-keyword">this</span>).scalarScheduleOn(scheduler); } <span class="hljs-keyword">return</span> create(<span class="hljs-keyword">new</span> OperatorSubscribeOn<T>(<span class="hljs-keyword">this</span>, scheduler)); }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>
什么意思呢?
Scheduler scheduler参数就是执行订阅操做,返回一个源观察到的修改,使其订阅发生在指定的线程
observeOn(AndroidSchedulers.mainThread())
句话说,observeOn() 指定的是它以后的操做所在的线程。
打印字符串数组 from和just方式
以上是RxJava的很基础很简单的一个用法,那么咱们接着往下看,好比咱们有一组需求把一个String数组的字符串,单个打印出来,咱们用Rxjava怎么实现呢?看代码:
<code class="hljs java has-numbering">Log.i(TAG, <span class="hljs-string">"testFunction: threadId:"</span> + Thread.currentThread().getId()); Observable.from(<span class="hljs-keyword">new</span> String[]{<span class="hljs-string">"one"</span>,<span class="hljs-string">"two"</span>,<span class="hljs-string">"three"</span>,<span class="hljs-string">"four"</span>}) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(<span class="hljs-keyword">new</span> Observer<String>() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCompleted</span>() { Log.d(TAG, <span class="hljs-string">"onCompleted: threadId:"</span> + Thread.currentThread().getId()); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onError</span>(Throwable e) { Log.e(TAG, <span class="hljs-string">"onError: threadId:"</span> + Thread.currentThread().getId()); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onNext</span>(String s) { Log.i(TAG, <span class="hljs-string">"onNext: s = "</span> + s); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul>
看Log输出日志以下:
<code class="hljs http has-numbering"><span class="hljs-attribute">testFunction</span>: <span class="hljs-string">threadId:1</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">s = one</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">s = two</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">s = three</span> <span class="hljs-attribute">onNext</span>: <span class="hljs-string">s = four</span> <span class="hljs-attribute">onCompleted</span>: <span class="hljs-string">threadId:1</span> </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>
From操做符用来将某个对象转化为Observable对象,而且依次将其内容发射出去。这个相似于just,可是just会将这个对象整个发射出去。好比说一个含有3个字符串的数组,使用from就会发射4次,每次发射一个数字,而使用just会发射一次来将整个的数组发射出去。
<code class="hljs lasso has-numbering"> <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"testFunction: threadId:"</span><span class="hljs-subst">+</span><span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); Observable<span class="hljs-built_in">.</span>just(<span class="hljs-string">"one"</span>, <span class="hljs-string">"two"</span>, <span class="hljs-string">"three"</span>, <span class="hljs-string">"four"</span>) <span class="hljs-built_in">.</span>subscribeOn(Schedulers<span class="hljs-built_in">.</span>io()) <span class="hljs-built_in">.</span>observeOn(AndroidSchedulers<span class="hljs-built_in">.</span>mainThread()) <span class="hljs-built_in">.</span>subscribe(<span class="hljs-literal">new</span> Observer<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onCompleted() { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>d(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onCompleted: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onError(Throwable e) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>e(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onError: threadId:"</span> <span class="hljs-subst">+</span> <span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); } @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> onNext(<span class="hljs-built_in">String</span> s) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"onNext: s = "</span> <span class="hljs-subst">+</span> s); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li></ul>
<code class="hljs mathematica has-numbering"><span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.743</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">I</span>/MainActivity: testFunction: threadId:<span class="hljs-number">1</span> <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.784</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">I</span>/MainActivity: onNext: s = one <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.785</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">I</span>/MainActivity: onNext: s = two <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.785</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">I</span>/MainActivity: onNext: s = three <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.785</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">I</span>/MainActivity: onNext: s = four <span class="hljs-number">03</span>-<span class="hljs-number">08</span> <span class="hljs-number">08</span>:<span class="hljs-number">09</span>:<span class="hljs-number">25.785</span> <span class="hljs-number">32155</span>-<span class="hljs-number">32155</span>/? <span class="hljs-keyword">D</span>/MainActivity: onCompleted: threadId:<span class="hljs-number">1</span> </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>
一对一转换
<code class="hljs lasso has-numbering"> <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"testFunction: threadId:"</span><span class="hljs-subst">+</span><span class="hljs-keyword">Thread</span><span class="hljs-built_in">.</span>currentThread()<span class="hljs-built_in">.</span>getId()); Observable<span class="hljs-built_in">.</span>just(<span class="hljs-string">"1"</span>, <span class="hljs-string">"2"</span>, <span class="hljs-string">"3"</span>, <span class="hljs-string">"4"</span>) <span class="hljs-built_in">.</span>subscribeOn(Schedulers<span class="hljs-built_in">.</span>io()) <span class="hljs-built_in">.</span>observeOn(AndroidSchedulers<span class="hljs-built_in">.</span>mainThread()) <span class="hljs-built_in">.</span><span class="hljs-built_in">map</span>(<span class="hljs-literal">new</span> Func1<span class="hljs-subst"><</span><span class="hljs-built_in">String</span>, <span class="hljs-built_in">Integer</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-built_in">Integer</span> call(<span class="hljs-built_in">String</span> s) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: s = "</span><span class="hljs-subst">+</span>s); <span class="hljs-keyword">return</span> <span class="hljs-built_in">Integer</span><span class="hljs-built_in">.</span>parseInt(s); } }) <span class="hljs-built_in">.</span>subscribe(<span class="hljs-literal">new</span> Action1<span class="hljs-subst"><</span><span class="hljs-built_in">Integer</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> call(<span class="hljs-built_in">Integer</span> <span class="hljs-built_in">integer</span>) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: integer = "</span><span class="hljs-subst">+</span><span class="hljs-built_in">integer</span>); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul>
<code class="hljs http has-numbering"><span class="hljs-attribute">testFunction</span>: <span class="hljs-string">threadId:1</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">s = 1</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">integer = 1</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">s = 2</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">integer = 2</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">s = 3</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">integer = 3</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">s = 4</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">integer = 4</span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
简单说一下Func1,其中的T表示传入的参数类型,R表示方法返回的参数类型。源码以下:
<code class="hljs php has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Func1</span><<span class="hljs-title">T</span>, <span class="hljs-title">R</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">Function</span> {</span> R call(T t); } </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
上例中还有一个叫作 Action1的类。也是 RxJava 的一个接口,用于包装含有无参数的方法。 Func1 和 Action 的区别在于, Func1 包装的是有返回值的方法。另外,和 ActionX 同样, FuncX 也有多个,用于不一样参数个数的方法。FuncX 和 ActionX 的区别在 FuncX 包装的是有返回值的方法。
能够看到,map() 方法将参数中的 String 对象转换成一个 Integer对象后返回,而在通过 map() 方法后,事件的参数类型也由 String 转为了 Integer。这种直接变换对象并返回的,是最多见的也最容易理解的变换。不过 RxJava 的变换远不止这样,它不只能够针对事件对象,还能够针对整个事件队列,这使得 RxJava 变得很是灵活。
封装Observable一对多转换
map转换,是一对一的转换,像示例当中,咱们把string转成int,可是当咱们须要一对多的转换,该怎么作呢?好比说,定义一个学生类:
<code class="hljs cs has-numbering">package com.example.administrator.myapplication; import java.util.List; <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> Student { <span class="hljs-keyword">private</span> String name; <span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span>() { <span class="hljs-keyword">return</span> name; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span>(String name) { <span class="hljs-keyword">this</span>.name = name; } <span class="hljs-comment"><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span><span class="hljs-xmlDocTag">///</span>//</span> <span class="hljs-keyword">private</span> List<String> courses; <span class="hljs-keyword">public</span> List<String> <span class="hljs-title">getCourses</span>() { <span class="hljs-keyword">return</span> courses; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCourses</span>(List<String> courses) { <span class="hljs-keyword">this</span>.courses = courses; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul>
<code class="hljs lasso has-numbering"> Student student1 <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> Student(); student1<span class="hljs-built_in">.</span>setName(<span class="hljs-string">"safly"</span>); <span class="hljs-built_in">List</span><span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span> courses <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> ArrayList<span class="hljs-subst"><></span>(); courses<span class="hljs-built_in">.</span>add(<span class="hljs-string">"语文"</span>); courses<span class="hljs-built_in">.</span>add(<span class="hljs-string">"数学"</span>); courses<span class="hljs-built_in">.</span>add(<span class="hljs-string">"英语"</span>); student1<span class="hljs-built_in">.</span>setCourses(courses); Student student2 <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> Student(); student2<span class="hljs-built_in">.</span>setName(<span class="hljs-string">"wyf"</span>); <span class="hljs-built_in">List</span><span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span> courses2 <span class="hljs-subst">=</span> <span class="hljs-literal">new</span> ArrayList<span class="hljs-subst"><></span>(); courses2<span class="hljs-built_in">.</span>add(<span class="hljs-string">"化学"</span>); courses2<span class="hljs-built_in">.</span>add(<span class="hljs-string">"地理"</span>); courses2<span class="hljs-built_in">.</span>add(<span class="hljs-string">"政治"</span>); student2<span class="hljs-built_in">.</span>setCourses(courses2); Observable<span class="hljs-built_in">.</span>just(student1,student2) <span class="hljs-built_in">.</span>subscribe(<span class="hljs-literal">new</span> Action1<span class="hljs-subst"><</span>Student<span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> call(Student student) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: name = "</span><span class="hljs-subst">+</span>student<span class="hljs-built_in">.</span>getName()); <span class="hljs-built_in">List</span><span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span> course <span class="hljs-subst">=</span> student<span class="hljs-built_in">.</span>getCourses(); for(<span class="hljs-built_in">String</span> str:course){ <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: str = "</span><span class="hljs-subst">+</span>str); } } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul>
这里咱们没有进行转换,直接just发送过来,没有用到转换,而后在call中进行直接输出了
<code class="hljs http has-numbering"><span class="hljs-attribute">call</span>: <span class="hljs-string">name = safly</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 语文</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 数学</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 英语</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">name = wyf</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 化学</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 地理</span> <span class="hljs-attribute">call</span>: <span class="hljs-string">str = 政治</span> </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
咱们用转换来试试看?
这里咱们用到了flatmap这一函数,按通俗的一点理解:咱们首先把Student转成了Observable,而后呢,又把student.getCourses()转成string挨个打印出来,结果以下:
<code class="hljs lasso has-numbering"> Observable<span class="hljs-built_in">.</span>just(student1,student2) <span class="hljs-built_in">.</span>flatMap(<span class="hljs-literal">new</span> Func1<span class="hljs-subst"><</span>Student, Observable<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">>></span>() { @Override <span class="hljs-keyword">public</span> Observable<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span> call(Student student) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"Observable "</span> ); <span class="hljs-keyword">return</span> Observable<span class="hljs-built_in">.</span>from(student<span class="hljs-built_in">.</span>getCourses()); } }) <span class="hljs-built_in">.</span>subscribe(<span class="hljs-literal">new</span> Action1<span class="hljs-subst"><</span><span class="hljs-built_in">String</span><span class="hljs-subst">></span>() { @Override <span class="hljs-keyword">public</span> <span class="hljs-literal">void</span> call(<span class="hljs-built_in">String</span> s) { <span class="hljs-keyword">Log</span><span class="hljs-built_in">.</span>i(<span class="hljs-built_in">TAG</span>, <span class="hljs-string">"call: s = "</span><span class="hljs-subst">+</span>s); } });</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul>
输出
<code class="hljs vbnet has-numbering"> Observable <span class="hljs-keyword">call</span>: s = 语文 <span class="hljs-keyword">call</span>: s = 数学 <span class="hljs-keyword">call</span>: s = 英语 Observable <span class="hljs-keyword">call</span>: s = 化学 <span class="hljs-keyword">call</span>: s = 地理 <span class="hljs-keyword">call</span>: s = 政治<span id="transmark"></span> </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
咱们还记得Observable.from嘛?
From操做符用来将某个对象转化为Observable对象
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <T> Observable<T> <span class="hljs-title">from</span>(Iterable<? extends T> iterable) { <span class="hljs-keyword">return</span> create(<span class="hljs-keyword">new</span> OnSubscribeFromIterable<T>(iterable)); }</code>