Rxjava学习记录(一)

来源:互联网 发布:node pm2 静态目录 编辑:程序博客网 时间:2024/06/11 23:42

1、Rxjava的基本介绍

RxJava是基于ReactiveX使用Java语言实现的版本,ReactiveX就是”观察者模式+迭代器模式+函数式编程”,它其实是一个扩展了的观察者模式,通过使用可观察的对象序列流来表述一系列事件,观察者可以依次处理不同的对象序列。
对应的,使用ReactiveX的实现方式,在Android上面类似Rxjava的框架叫RxAndroid。

2、Rxjava的核心

RxJava最核心的两个东西就是Observables(被观察者,也就是事件源)和Observer(观察者,事件的消费者),在Rxjava中观察者Observer不是直接出现的,通常是由Subscribers(英文的意思是订阅者,观察者和订阅者傻傻分不清,其实是父类和子类,不知道为何要这样命名)继承自Observer,由Observables发出一系列的事件,Subscribers进行订阅接收并进行处理。Subscribers在整个过程充当的是观察者的角色。

3、Rxjava的使用

先新建个工程,在build.gradle里面引入rxjava

    compile 'io.reactivex:rxjava:1.0.14'    compile 'io.reactivex:rxandroid:1.0.1'

使用获取天气预报测试,我们就使用新浪提供的API接口吧,地址如下:
http://php.weather.sina.com.cn/xml.php?city=%B1%B1%BE%A9&password=DJOYnieT8234jlsK&day=0

其中,city后的是城市转码,Password固定值,不关心,Day为0表示当天天气,1表示第二天的天气,2表示第三天的天气,以此类推,最大为4

布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="androidsm2.libcom.com.rxjavatest2.MainActivity">    <LinearLayout        android:layout_width="368dp"        android:layout_height="wrap_content"        android:orientation="vertical"        tools:layout_editor_absoluteY="0dp"        tools:layout_editor_absoluteX="8dp">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:background="#FF0000"            android:weightSum="1">            <EditText                android:id="@+id/city"                android:layout_width="275dp"                android:layout_marginTop="8dp"                android:layout_marginBottom="8dp"                android:layout_marginLeft="10dp"                android:layout_marginRight="10dp"                android:paddingLeft="15dp"                android:paddingRight="15dp"                android:gravity="center_vertical"                android:layout_height="wrap_content"                android:hint="请输入城市"                android:layout_weight="0.81" />            <Button                android:id="@+id/query"                android:layout_width="80dp"                android:layout_height="match_parent"                android:text="查询"                android:gravity="center"                android:textColor="#FFFFFF"                android:layout_gravity="center_vertical"/>        </LinearLayout>        <TextView            android:id="@+id/weather"            android:layout_width="match_parent"            android:layout_height="390dp"            android:layout_margin="10dp" />    </LinearLayout></android.support.constraint.ConstraintLayout>

MainAcitivty

package androidsm2.libcom.com.rxjavatest2;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLEncoder;import rx.Observable;import rx.Subscriber;import rx.Subscription;import rx.android.schedulers.AndroidSchedulers;import rx.schedulers.Schedulers;import static androidsm2.libcom.com.rxjavatest2.Utils.parseWeather;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final String WEATHRE_API_URL = "http://php.weather.sina.com.cn/xml.php?city=%s&password=DJOYnieT8234jlsK&day=0";    private Button queryBtn;    private EditText cityEd;    private TextView weatherTv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        queryBtn = (Button) findViewById(R.id.query);        cityEd = (EditText) findViewById(R.id.city);        weatherTv = (TextView) findViewById(R.id.weather);        queryBtn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        final String cityStr = cityEd.getText().toString();        if (v.getId() == R.id.query) {            rxTest(cityStr);        }    }    /**     * 获取指定城市的天气情况     *     * @param city     * @return     * @throws     */    private String getWeather(String city) {        BufferedReader reader = null;        HttpURLConnection connection = null;        String result = "";        try {            String urlString = String.format(WEATHRE_API_URL, URLEncoder.encode(city, "GBK"));            URL url = new URL(urlString);            connection = (HttpURLConnection) url.openConnection();            connection.setRequestMethod("GET");            connection.setReadTimeout(5000);            //连接            connection.connect();            //处理返回结果            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));            StringBuffer buffer = new StringBuffer();            String line = "";            while (!TextUtils.isEmpty(line = reader.readLine()))                buffer.append(line);            result = buffer.toString();            Log.d("TAG", "result-->" + result);        } catch (IOException e) {            e.printStackTrace();        } finally {            if (connection != null) {                connection.disconnect();            }            if (reader != null) {                try {                    reader.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return result;    }    private void rxTest(final String cityStr){        //被观察者创建一个被观察对象,并构建一个订阅者,由订阅者回调这个执行结果        Observable<Weather> myObservable = Observable.create(new Observable.OnSubscribe<Weather>() {            @Override            public void call(Subscriber<? super Weather> subscriber) {                Weather weather = Utils.parseWeather(getWeather(cityStr));                subscriber.onNext(weather);                subscriber.onCompleted();            }        })         //被观察者在新线程        .subscribeOn(Schedulers.newThread())        //观察者在主线程        .observeOn(AndroidSchedulers.mainThread());        //订阅者Subscriber其实是继承观察者Observer        Subscriber<Weather> mySubscriber = new Subscriber<Weather>() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {                Log.e("TAG","e-->" + e);            }            @Override            public void onNext(Weather weather) {                Log.e("TAG","weather-->" + weather);            }        };        //被观察者通过subscribe订阅关系,把事件传给订阅者(观察者)        myObservable.subscribe(mySubscriber);    }}

这个有两行代码要特别注意的地方就是:

       //被观察者在新线程        .subscribeOn(Schedulers.newThread())        //观察者在主线程        .observeOn(AndroidSchedulers.mainThread());
在4.x以上版本网络连接必须开单独的线程进行处理,否则就会报NetWorkRunInUI····的错误,所以在构造这个被观察者的时候先要处理好线程,而Schedulers类是Rxjava中非常重要的一个类。

大致过程:
1、创建一个被观察者对象,并指定被观察的数据类型是Weather对象。
2、构建观察者的时候要指定线程的执行状况,否则会报错
3、onNext()、onCompleted()和onError()是3个关键的回调方法

其他非核心代码Weather.java:

package androidsm2.libcom.com.rxjavatest2;/** * Created by Administrator on 2017/12/19. * @time 2017/12/19 15:03 * @change * @class describe */public class Weather {    /**     * 城市     */    String city;    /**     * 日期     */    String date;    /**     * 温度     */    String temperature;    /**     * 风向     */    String direction;    /**     * 风力     */    String power;    /**     * 天气状况     */    String status;    @Override    public String toString() {        StringBuilder builder = new StringBuilder();        builder.append("城市:" + city + "\r\n");        builder.append("日期:" + date + "\r\n");        builder.append("天气状况:" + status + "\r\n");        builder.append("温度:" + temperature + "\r\n");        builder.append("风向:" + direction + "\r\n");        builder.append("风力:" + power + "\r\n");        return builder.toString();    }}

Utils.java

package androidsm2.libcom.com.rxjavatest2;import android.support.annotation.Nullable;import android.util.Xml;import org.xmlpull.v1.XmlPullParser;import java.io.StringReader;/** * Created by Administrator on 2017/12/19. * @class describe */public class Utils {    @Nullable    public static Weather parseWeather(String weatherXml){        //采用Pull方式解析xml        StringReader reader = new StringReader(weatherXml);        XmlPullParser xmlParser = Xml.newPullParser();        Weather weather = null;        try {            xmlParser.setInput(reader);            int eventType = xmlParser.getEventType();            while(eventType != XmlPullParser.END_DOCUMENT){                switch (eventType){                    case XmlPullParser.START_DOCUMENT:                        weather = new Weather();                        break;                    case XmlPullParser.START_TAG:                        String nodeName = xmlParser.getName();                        if("city".equals(nodeName)){                            weather.city = xmlParser.nextText();                        } else if("savedate_weather".equals(nodeName)){                            weather.date = xmlParser.nextText();                        } else if("temperature1".equals(nodeName)) {                            weather.temperature = xmlParser.nextText();                        } else if("temperature2".equals(nodeName)){                            weather.temperature += "-" + xmlParser.nextText();                        } else if("direction1".equals(nodeName)){                            weather.direction = xmlParser.nextText();                        } else if("power1".equals(nodeName)){                            weather.power = xmlParser.nextText();                        } else if("status1".equals(nodeName)){                            weather.status = xmlParser.nextText();                        }                        break;                }                eventType = xmlParser.next();            }            return weather;        } catch(Exception e) {            e.printStackTrace();            return null;        } finally {            reader.close();        }    }}

参考链接:
http://blog.csdn.net/Job_Hesc/article/details/45798307
http://blog.csdn.net/u010072711/article/details/51590553

原创粉丝点击