RxJava 2修練の道(二)
8787 ワード
RaJava 2修練の道——易容術
前編でRxJavaの原理を説明した後、本編ではRxJavaがタスクを実行するスレッドのスケジューリングについてさらに深く理解します.
目的
Androidを習ったばかりのシロにとって、覚えておきたいのは、サブスレッドが新しいUIに接続できないことです.新しいUIとの操作はすべてメインスレッド(つまりUIスレッド)に置かなければなりません.何を聞きますか.インタフェースカートンやANRになるから、ANRとは何か聞きたいなら?では、まず資料を調べて充電してから、この文章を見てみましょう.新しいUIとの操作がサブスレッドでプログラムが潰れてしまいます.次は私が書いた例です.Handlerを利用して新しいUIと付き合います.
簡単なネットワークロード画像であり、UIインタフェースに表示され、OnResumeでスレッドを開いてロード画像を実行する時間のかかる操作であり、画像ロードが完了した後、メッセージに画像を埋め込んでHandlerMessageに伝え、UIを実行して新しいものを実行し、HandlerはAndroidの重要な知識点であり、よく分からない仲間は資料を調べて補足しましょう.
インプリメンテーション
まず、RxJavaでのイベントの送信と受信を見てみましょう.
印刷結果:
明らかに、送信イベントと受信イベントのデフォルトはMain、すなわちUIスレッドです.では、送信イベントをサブスレッドに、新しいイベントをUIスレッドにするにはどうすればいいのでしょうか.ここでは,RxJavaのスレッドスケジューラSchedulerという新しい概念を導入し,Schedulers内部には6つのスケジューリングタイプが含まれている. Schedulers.イベントループやコールバック処理などのタスクの計算に使用され、IO操作では使用されません(IO操作はSchedulers.io()を使用してください).デフォルトのスレッド数は、プロセッサの数に等しい Schedulers.from(executor)は、指定されたExecutorをスケジューラ として使用する. Schedulers.immediate( Schedulers.io( )は、非同期でIO操作をブロックするなど、IO密集型タスクに使用され、このスケジューラのスレッドプールは必要に応じて増加します.通常の計算タスクでは、Schedulersを使用します.computation();Schedulers.io( )デフォルトはCachedThreadSchedulerであり、スレッドキャッシュされた新しいスレッドスケジューラ に似ています. Schedulers.新Thread( )は、タスクごとに新しいスレッド を作成する. Schedulers.trampoline( )他のキューのタスクが完了すると、現在のスレッドキューで実行が開始されます.また、 という特殊なスケジューリングタイプもあります.
AndroidSchedulers.mainThread()このスケジューリングタイプはUIスレッドで発生する唯一の決定である
上はスレッドスケジューラの6つのタイプで、いずれもSchedulesクラスの静的定数です.次は変身の時だ.
印刷結果:
案の定、イベントをサブスレッドに送信し、新しいメインスレッドでの操作を完了し、次に画像のダウンロード更新をRxJavaに置いて実行します.
では、画像は正常に表示されます.それなら、onSubscribeとonObserverでスレッドを何度も指定したら?たとえば、次のようになります.
印刷結果:
サブスクリプションイベント選択が最も近いスレッドスケジューリング方式を設定し、観察者が最後のスレッドスケジューリング方式を選択することを説明できます.サブスレッドサブスレッドオブザーバでサブスレッドオブザーバを完了した以上、このような処理に時間がかかるタスクの過程でActivityは破棄されますか?ここでは前編のDisposiableオブジェクトを用い,Activity破棄時にイベント送信を終了する.
では、Disposableが複数あるとしたら?ここにはDisposable専用の容器類CompositeDisposableがあり、中には`OpenHashSet resourcesがメンテナンスされています.集合ですので、登録時にDisposableをCompositeDisposableに追加し、Activity破棄時にその容器Clearを落とすだけです.さて、RxJavaのイベントスケジューリングは、イベント実行のスレッドを変更するために使用されます.
前編でRxJavaの原理を説明した後、本編ではRxJavaがタスクを実行するスレッドのスケジューリングについてさらに深く理解します.
目的
Androidを習ったばかりのシロにとって、覚えておきたいのは、サブスレッドが新しいUIに接続できないことです.新しいUIとの操作はすべてメインスレッド(つまりUIスレッド)に置かなければなりません.何を聞きますか.インタフェースカートンやANRになるから、ANRとは何か聞きたいなら?では、まず資料を調べて充電してから、この文章を見てみましょう.新しいUIとの操作がサブスレッドでプログラムが潰れてしまいます.次は私が書いた例です.Handlerを利用して新しいUIと付き合います.
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "handleMessage: "+Thread.currentThread().getName());
if(msg.what == 0x01){
Bitmap bmp = (Bitmap) msg.obj;
loadPic(bmp);
}
}
};
/**
* UI
*
* @param bmp
*/
private void loadPic(Bitmap bmp) {
img.setImageBitmap(bmp);
}
@Override
protected void onResume() {
super.onResume();
new Thread() {//
@Override
public void run() {
Bitmap bmp = loadImage();
Message msg = handler.obtainMessage();
msg.obj = bmp;
msg.what = 0x01;
handler.sendMessage(msg);
}
}.start();
}
/**
*
*
* @return
*/
private Bitmap loadImage() {
Bitmap bmp = null;
try {
URL url = new URL(mUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(8 * 1000);
conn.setReadTimeout(8 * 1000);
InputStream is = conn.getInputStream();
bmp = BitmapFactory.decodeStream(is);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);// handler
}
簡単なネットワークロード画像であり、UIインタフェースに表示され、OnResumeでスレッドを開いてロード画像を実行する時間のかかる操作であり、画像ロードが完了した後、メッセージに画像を埋め込んでHandlerMessageに伝え、UIを実行して新しいものを実行し、HandlerはAndroidの重要な知識点であり、よく分からない仲間は資料を調べて補足しましょう.
インプリメンテーション
まず、RxJavaでのイベントの送信と受信を見てみましょう.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
e.onNext("hello world");
e.onComplete();
}
}).subscribe(new Consumer() {
@Override
public void accept(String str) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
}
});
}
印刷結果:
09-02 10:34:10.065 22364-22364/ruanrong.com.rxjava2demo D/tag: subscribe: main
09-02 10:34:10.067 22364-22364/ruanrong.com.rxjava2demo D/tag: accept: main
明らかに、送信イベントと受信イベントのデフォルトはMain、すなわちUIスレッドです.では、送信イベントをサブスレッドに、新しいイベントをUIスレッドにするにはどうすればいいのでしょうか.ここでは,RxJavaのスレッドスケジューラSchedulerという新しい概念を導入し,Schedulers内部には6つのスケジューリングタイプが含まれている.
AndroidSchedulers.mainThread()このスケジューリングタイプはUIスレッドで発生する唯一の決定である
上はスレッドスケジューラの6つのタイプで、いずれもSchedulesクラスの静的定数です.次は変身の時だ.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.d(TAG, "subscribe: "+Thread.currentThread().getName());
e.onNext("hello world");
e.onComplete();
}
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(String str) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
}
});
}
印刷結果:
09-02 10:59:12.717 12326-12357/ruanrong.com.rxjava2demo D/tag: subscribe: RxNewThreadScheduler-1
09-02 10:59:12.729 12326-12326/ruanrong.com.rxjava2demo D/tag: accept: main
案の定、イベントをサブスレッドに送信し、新しいメインスレッドでの操作を完了し、次に画像のダウンロード更新をRxJavaに置いて実行します.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
Bitmap bmp = loadImage();
e.onNext(bmp);
e.onComplete();
}
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(Bitmap bitmap) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
img.setImageBitmap(bitmap);
}
});
では、画像は正常に表示されます.それなら、onSubscribeとonObserverでスレッドを何度も指定したら?たとえば、次のようになります.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
e.onNext("hello world");
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.newThread())
.subscribe(new Consumer() {
@Override
public void accept(String str) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
}
});
}
印刷結果:
09-02 11:09:51.315 21666-21686/? D/tag: subscribe: RxNewThreadScheduler-1
09-02 11:09:51.329 21666-21688/? D/tag: accept: RxNewThreadScheduler-2
サブスクリプションイベント選択が最も近いスレッドスケジューリング方式を設定し、観察者が最後のスレッドスケジューリング方式を選択することを説明できます.サブスレッドサブスレッドオブザーバでサブスレッドオブザーバを完了した以上、このような処理に時間がかかるタスクの過程でActivityは破棄されますか?ここでは前編のDisposiableオブジェクトを用い,Activity破棄時にイベント送信を終了する.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.d(TAG, "accept: "+Thread.currentThread().getName());
Bitmap bmp = loadImage();
e.onNext(bmp);
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
mDisposable = d;
}
@Override
public void onNext(Bitmap value) {
img.setImageBitmap(value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
if(!mDisposable.isDisposed()){
mDisposable.dispose();
}
}
では、Disposableが複数あるとしたら?ここにはDisposable専用の容器類CompositeDisposableがあり、中には`OpenHashSet resourcesがメンテナンスされています.集合ですので、登録時にDisposableをCompositeDisposableに追加し、Activity破棄時にその容器Clearを落とすだけです.さて、RxJavaのイベントスケジューリングは、イベント実行のスレッドを変更するために使用されます.