rxAndroid小結

部分參考了作者 飛奔的螞蟻

初識rxAndroid

1.rxAndroid涉及對象:訂閱者(觀察者),被觀察者以及訂閱事件


訂閱者與觀察者

被觀察者可以理解為數據源,它可以向訂閱者(觀察者)發送數據消息和消息,而訂閱者則通過被觀察者發送的消息做出相應的動作。而rxAndroid本身也提供了線程切換的API,可以分別指定訂閱者和被觀察者的線程。
每一段rxAndroid代碼都從被觀察者開始

observables 被觀察者(事件源)
subscribers 觀察者 訂閱者
schedulers 子線程、主線程切換的調度 器,
schedulers.newThread() 在子線程中執行,
schedulers.mainThread()在主線程中執行,
schedulers.io(),訪問網絡和數據操作的線程執行

核心代碼

Observable.subscribe(Subcribe);

其中被觀察者通過call回調subscriber.onNext(數據)和onComplete()傳遞數據,而subcscriber實現onNext(數據){....},加上線程控制從而實現異步任務處理。

下面舉個栗子:從網絡獲取json數據:
package com.example.rxtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


public class MainActivity extends AppCompatActivity {


    private static final String TAG = "MainActivity";


    @BindView(R.id.btn_search)
    Button btnSearch;
    @BindView(R.id.tv_result)
    TextView tvResult;

    String requestUrl = "http://www.cnblogs.com/whoislcj/p/5520384.html";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                createSubscription();
            }
        });

    }

    private void createSubscription() {
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {

                String s = loadText();
                subscriber.onNext(s);
                subscriber.onCompleted();
            }
        })//被觀察者
                .subscribeOn(Schedulers.io())//指定上面的被觀察者在io線程(階級數據、訪問網絡)
                .observeOn(AndroidSchedulers.mainThread())//指定下面的訂閱者的線程(UI線程)
                .subscribe(new Subscriber<String>() {//訂閱者
                    @Override
                    public void onStart() {
                        tvResult.setText("開始加載..");
                    }

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        tvResult.setText("加載出錯" + e.getMessage());

                    }

                    @Override
                    public void onNext(String s) {
                        //被觀察者onnext傳遞過來的消息
                        tvResult.setText(s);
                    }
                });
    }

    private String loadText() {
        // 新建一個URL對象
        URL url = null;
        String result = null;

        try {
            url = new URL(requestUrl);

            // 打開一個HttpURLConnection連接
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            // 設置連接主機超時時間
            urlConn.setConnectTimeout(5 * 1000);
            //設置從主機讀取數據超時
            urlConn.setReadTimeout(5 * 1000);
            // 設置是否使用緩存  默認是true
            urlConn.setUseCaches(true);
            // 設置為Get請求
            urlConn.setRequestMethod("GET");
            //urlConn設置請求頭信息
            //設置請求中的媒體類型信息。
            urlConn.setRequestProperty("Content-Type", "application/json");
            //設置客戶端與服務連接類型
            urlConn.addRequestProperty("Connection", "Keep-Alive");
            // 開始連接
            urlConn.connect();
            // 判斷請求是否成功
            if (urlConn.getResponseCode() == 200) {
                // 獲取返回的數據
                result = streamToString(urlConn.getInputStream());
                Log.e(TAG, "Get方式請求成功,result--->" + result);
            } else {
                Log.e(TAG, "Get方式請求失敗");
            }
            // 關閉連接
            urlConn.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }

        return result;
    }

    private String streamToString(InputStream inputStream) {

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer buffer = new StringBuffer();
        String line;

        try {
            while ((line = bufferedReader.readLine()) != null){
                buffer.append(line);
            }

            bufferedReader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return buffer.toString();
    }

}

如圖


rxAndroid簡單示例

rxAndroid操作符

map操作符

map 用來操作observable和最終的subscriber之間修改observable發出事件的類型,比如發出類型為int類型,最終為String類型,中間用map來轉換

from操作符

將其他種類的對象和數據類型轉換為Observable
當你使用Observable時,如果你要處理的數據都可以轉換成展現為Observables,而不是需要使用Observables和其他類型的數據

/**
     * 使用在被觀察者,返回的對象一般都是數值類型
     */
    public static void from(){
        Integer [] items={1,2,3,4,5,6,7,8,9};
        Observable observable = Observable.from(items);
        observable.subscribe(new Action1() {
            @Override public void call(Object o) {
                Log.i("adu",o.toString());
            }
        });
    }
interval操作符

interval操作符既可以延遲執行一段邏輯

/**
     * 指定某一時刻進行數據發送
     */
    public static void interval(){
        Integer [] items = {1,2,3,4,5};
        Observable observable = Observable.interval(items,1, TimeUnit.SECONDS);//每隔一秒發送數據
        observable.subscribe(new Action1() {
            @Override public void call(Object o) {
                Log.i("adu",o.toString());
            }
        });
    }
just

獲取輸入數據, 直接分發, 更加簡潔, 省略其他回調.

/**
     * 處理數組集合
     */
    public static void just(){
        Integer[] items1={1,2,3,4,5};
        Integer[] items2={4,5,1,6,0};
        Observable observable = Observable.just(items1,items2);
        observable.subscribe(new Subscriber<Integer[]>() {
            @Override public void onCompleted() {
                Log.i("adu","onCompleted");
            }
            @Override public void onError(Throwable e) {
                Log.i("adu","onError");
            }
            @Override public void onNext(Integer[] integers) {
                for (int i= 0;i<integers.length;i++){
                    Log.i("adu","onNext==》》"+integers[i]);//先打印items1再打印items2
                }
            }
        });
    }
range操作符

range操作符的作用根據出入的初始值n和數目m發射一系列大于等于n的m個值。

/**
     * 指定輸出數據的范圍
     */
    public static void range(){
        Observable observable = Observable.range(23,4);
        observable.subscribe(new Subscriber<Integer>() {
            @Override public void onCompleted() {
                Log.i("adu","onCompleted");
            }
            @Override public void onError(Throwable e) {
                Log.i("adu","onError");
            }
            @Override public void onNext(Integer integer) {
                Log.i("adu","onNext==》》"+integer);
            }
        });
    }
flter操作符

數據過濾器,比如得到大于或者小于某個數的值

/**
     * 過濾某些條件
     */
    public static void filter(){
        Observable observable = Observable.just(1,2,3,4,5,6,7,8);
        observable.filter(new Func1<Integer,Boolean>() {
            @Override public Boolean call(Integer integer) {
                return integer<5;
            }
        }).observeOn(Schedulers.io()).subscribe(new Subscriber<Integer>() {
            @Override public void onCompleted() {
                Log.i("adu","onCompleted");
            }
            @Override public void onError(Throwable e) {
                Log.i("adu","onError");
            }
            @Override public void onNext(Integer integer) {
                Log.i("adu","inNext==》》"+integer);
            }
        });
    }
take操作符

獲取數據前幾位值

takelast操作符

獲取數據后幾位值

deitinct

對一個值只處理一次

等等操作,詳情參考rxAndroid操作

CompositeSubscription

用于訂閱者的管理,一般在baseActivity中創建,將所有訂閱者添加到CompositeSubcription中集中管理.

add()添加訂閱者
clear()清理訂閱者,可以再次使用
unsubscribe()取消訂閱者,再也不能使用

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容