編輯:關於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來創建一個被觀察著
ObservablemObservable= Observable.create(new Observable.OnSubscribe () { @Override public void call(Subscriber subscriber) { subscriber.onNext("heloo rxjava"); subscriber.onCompleted(); } });
Observable的靜態方法 create接受一個OnSubscribe,這是一個什麼,可以這樣理解, 它的作用相當於一個計劃表,當 Observable 被訂閱的時候,OnSubscribe 的 call() 方法會自動被調用,事件序列就會依照設定依次觸發。
然後創建好了被觀察著,我們再來創建觀察者
SubscribermSubscriber= 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。
這麼長???這只是為了理解。下面為精簡做准備。
首先創建被觀察者,可以簡化,比如
Listmlist = 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
前幾天在“Android繪圖之漸隱動畫”一文中通過畫線實現了漸隱動畫,但裡面有個問題,畫筆較粗(大於1)時線段之間會有裂隙,我又改進了一下。這次效果好多了。先看效果吧:然
cardView:添加依賴:在Studio搜索cardview即可 在V7包中或者直接在gradle中添加compile 'com.android.support
本文實例講述了Android編程之canvas繪制各種圖形的方法。分享給大家供大家參考,具體如下:1、首先說一下canvas類:Class OverviewThe Can
我不知道大家有沒有這樣問題,項目做多了,就容易忽略最最基礎的知識,其實我也是在最近發現了自己也存在這樣的問題。因此打算做一些最基礎的知識的調研來重新學習和回顧這些容易被忽