Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> rxjava/rxandroid結合lambda的使用

rxjava/rxandroid結合lambda的使用

編輯:關於Android編程

發覺最近看到rxjava用的人好多也學習了一下,打算用在項目裡面,提升下開發速度和縮減代碼!!!現在的項目代碼過於冗雜了。用rxjava結合lambda來縮小代碼篇幅。
當你熟悉了以後,你會發現這東西簡直 diao爆了,太好用了,既縮短了代碼,而且避免了惡心的匿名類,代碼結構清晰明了。
rxandroid相當於是 rxjava在android的擴展,針對android很多都能簡化。 這裡說部分簡單的案例。
不知道或者不了解rxandroid的可以看看大牛寫的博客先了解下原理,這裡只所說應用了。

gradle要添加如下配置

    compile 'com.trello:rxlifecycle:0.6.1'
    compile 'com.trello:rxlifecycle-components:0.6.1'
    compile 'io.reactivex:rxjava:1.1.6'
    compile 'io.reactivex:rxandroid:1.2.1' // RxAndroid

rxlifecycle是解決rxjava內存洩漏准備的開源框架。
添加這些就能使用rxjava/rxandroid了。
還想不想讓代碼更簡潔? 那麼就來lambda吧。
在studio裡面,引用lambda表達式,需要在model的gradle裡面添加

apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'


buildscript {
    repositories {
        jcenter();
        mavenCentral()
    }
    dependencies {
        classpath 'me.tatarka:gradle-retrolambda:3.2.5'
    }
}
repositories {
    mavenCentral()
}

添加到apply plugin: ‘com.android.application’下面就行。
gradle的配置ok了,然後構建項目。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面正式開始說下使用
1rxjava 的使用類似於觀察者模式,有被觀察者Observable,和觀察者Subscriber,當然還有把它們兩個關聯起來的訂閱subscribe。這裡的訂閱是 Observable的方法,是因為為了保持鏈式結構,縮短代碼。

先來一個完整的寫法,首先是創建一個觀察者
創建觀察者的方法有很多,Observable類提供了create方法來創建,也有from方法來接受一個集合,也有just方法來接受n個對象來創建。
這裡先來用create來創建一個被觀察著

Observable mObservable= Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                subscriber.onNext("heloo rxjava");
                subscriber.onCompleted();
            }
        });

Observable的靜態方法 create接受一個OnSubscribe,這是一個什麼,可以這樣理解, 它的作用相當於一個計劃表,當 Observable 被訂閱的時候,OnSubscribe 的 call() 方法會自動被調用,事件序列就會依照設定依次觸發。
然後創建好了被觀察著,我們再來創建觀察者

Subscriber mSubscriber= new Subscriber() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError");
            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, s);
            }
        };

觀察者 也創建好了。和被觀察者一樣,也帶有泛型。 觀察者有三個方法,onnext方法就是被觀察者的call方法裡面調用的。 然後,call執行完成就都會調用觀者的 onCompleted方法,如果執行中出錯了,那麼就會調用onError了,不會再去調用onCompleted了。
最後是訂閱

 mObservable.compose(this.bindUntilEvent(ActivityEvent.DESTROY)).subscribe(mSubscriberriber);

經過上面三步就可以用了,代碼加一起是這樣的

   mObservable = Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                subscriber.onNext("heloo rxjava");
                subscriber.onCompleted();
            }
        });
        mSubssscriber = new Subscriber() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError");
            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, s);
            }
        };
        mObservable.compose(this.bindUntilEvent(ActivityEvent.DESTROY)).subscribe(mSubssscriber);

正常運行上面代碼先輸出heloo rxjava然後輸出onCompleted。
這麼長???這只是為了理解。下面為精簡做准備。
首先創建被觀察者,可以簡化,比如

 List mlist = new ArrayList<>();
        mlist.add("my is  11111");
        mlist.add("my is  222");
        mlist.add("my is  333");
        Observable.from(mlist).
 Observable.just("this is 111", "this is 22", "this is 333")

然後,這比create簡單多了。然後是創建觀察者,三個方法可以精簡,rxjava的Action1就訴帶一個參數的方法,能 和call匹配。
再加一點,這完全可以寫成鏈式結構,干嗎分散三步? 於是

        Observable.just("hello ").
                   subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, s);
                    }
                });
  代碼是不是少了很多。還可以更少哦 。lambda來吧
 Observable.just("this is first string", "this is second")  .subscribe(s -> Log.e(TAG, s));

這就是精簡後的代碼,比起原來簡單了很多。
運行會打印出來this is first string”, “this is second。

rxjava有著強大的操作符,用的多的比如說map
map可以接受一個泛型的類型,然後一個泛型指定的數據,然後繼續給subscribe訂閱用。
例子

   Observable.just("this is 111", "this is 22", "this is 333").map(new Func1() {

            @Override
            public String call(String s) {
           return  s+"!!";
            }
        }).subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, s);
                    }
                });

遍歷三個字符串,然後每一個添加!!然後輸出。 用lambda簡化一下就是

   Observable.just("this is 111", "this is 22", "this is 333").map(s -> s + "!!").subscribe(s -> Log.e(TAG, s));

是不是簡化了太多。
然後在說一下flatMap 。map是來返回一個自定義類型的變量,而莪flatmap返回的是代泛型的被觀察者Observable。。為啥返回這個呢。 他相當對原來的被觀察著進行一些處理,然後在返回回去,供下面的使用。。。。 看一個例子

   Observable.just("helloworld ").flatMap(new Func1>() {
            @Override
            public Observable call(String s) {
                return Observable.just(s + "@##");
            }
        }).   subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, s);
                    }
                });

flatmap接受一個string,然後返回string的Observable,給subscribe訂閱用。
再看一個flatmap例子

 List mlist = new ArrayList<>();
        mlist.add("my is  11111");
        mlist.add("my is  222");
        mlist.add("my is  333");
        Observable.from(mlist).
                flatMap(new Func1>() {
                    @Override
                    public Observable call(String s) {
                        return Observable.just(s + "   button 5");
                    }
                }). subscribe(new Action1() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, s);
                    }
                });

上面的代碼,遍歷結合,然後每一個字符串末尾添加button5。
簡化一下就是

 List mlist = new ArrayList<>();
        mlist.add("my is  111");
        mlist.add("my is  222");
        mlist.add("my is  333");
        Observable.from(mlist).flatMap(s -> Observable.just(s + " button  6"))
                .flatMap(s -> Observable.just(s + "~~")).doOnNext(s -> Log.e(TAG, "doOnNext    " + s)).subscribe(s1 -> Log.e(TAG, s1));

donext多了一個方法,這個方法是在觀察者call(onnext)方法執行之前回調用的。

下面說下rxjava在線程方面的應用。

   Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                for (int i = 0; i < 20; i++) {
                    try {
                        res++;
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                subscriber.onNext(res + "");
            }
        }).subscribeOn(Schedulers.newThread())//OnSubscribe線程
                .observeOn(AndroidSchedulers.mainThread())//Observer 線程
                    .subscribe(new Observer() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        mtext.setText(s);
                        Log.e(TAG, s);
                    }
                });

OnSubscribe 在newThread裡面也就是新線程裡面耗時操作,然後主線程在更改ui。
其中的subscribeOn指定OnSubscribe 在哪個線程運行,observeOn決定了Observer也就是觀察者在哪裡運行。

用運lambda表達式簡化一下就是

  Observable.create(subscriber -> {
            for (int i = 0; i < 20; i++) {
                resss++;
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            subscriber.onNext(resss);
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> mtext.setText(s + " button  lambda thread"));

ok。下面說一下rxjava內存洩漏的問題。解決這個問題運用的是開頭gradle引用的開源項目。
然後修改activity為繼承RxAppCompatActivity 或者RxActivity。然後在使用時候調用一下.compose(this.bindUntilEvent(ActivityEvent.DESTROY))。這樣就在activity銷毀時候釋放了contexxt的引用
防止內存洩漏

 Observable.just("this is first string", "this is second")
                .compose(this.bindUntilEvent(ActivityEvent.DESTROY)).subscribe(s -> Log.e(TAG, s));

除了ActivityEvent.DESTROY以外還有其他可以選擇的時候
CREATE,
START,
RESUME,
PAUSE,
STOP,
DESTROY

那麼compose和flatMap()有啥區別?

compose()和flatMap()有啥區別呢。他們都是發射出Observable,是不是就是說他們都可以復用一系列操作符呢?

區別在於compose()是高等級的抽象,他操作的是整個流,而不是單一發射出的項目,這裡有更多的解釋:

compose()
是唯一一個能從流中獲取原生Observable 的方法,因此,影響整個流的操作符(像subscribeOn()和observeOn())需要使用compose(),相對的,如果你在flatMap()中使用subscribeOn()/observeOn(),它只影響你創建的flatMap()中的Observable,而不是整個流。
當你創建一個Observable流並且內聯了一堆操作符以後,compose()會立即執行,flatMap()則是在onNext()被調用以後才會執行,換句話說,flatMap()轉換的是每個項目,而compose()轉換的是整個流。
flatMap()
一定是低效率的,因為他每次調用onNext()之後都需要創建一個新的Observable,compose()是操作在整個流上的。

rxjava入門應用大約就是這些,基本的會用了,等後面在研究下深入的。

下面說下rxandroid的應用。
還在苦苦的setonclick ontiemclick各種內部類麼?亂亂亂。 rxandroid簡化了代碼,看例子

 RxView.clicks(findViewById(R.id.btn10)).subscribe((v) -> Log.e(TAG, "rxview->click"));

這一行就夠了,結合lambda是如此簡潔。
itemclick一樣如此。

RxAdapterView.itemClicks(mlistview).subscribe(positon -> Log.e(TAG, positon + "位置"));

其他用法也在發現中,會把這當成筆記寫在這裡。
demo地址:https://github.com/836154942/rxjavademo

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved