RxJava2, RxAndroid2

[RxAndroid2] RxAndroid로 안드로이드 스레드 대체하기. AndroidSchedulers.mainThread()

알통몬_ 2018. 10. 10. 11:15
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 


안드로이드는 기본적으로 싱글 스레드 모델이기 때문에

처리하는데 시간이 오래걸리는 데이터의 전송이나

파일의 입출력 등은 별도의 스레드로 분리하여서 작업을 해야 합니다.

그렇지 않으면 앱의 성능이 나빠지거나, 앱이 응답하지 않는 일이

발생하기도 합니다.


스레드를 효과적으로 관리하려면 스케줄러를 만들어서 관리해야 하는데요.

Rx 프로그래밍에서 안드로이드의 스레드를 어떻게 구현하는지 공부합니다.


안드로이드의 View or ViewGroup 은 UI 스레드에서만 업데이트할 수 있도록

설계되어 있는데, 그 이유는 여러 스레드에서 동시에 UI를 업데이트할 때

발생할 수도 있는 동기화 문제를 사전에 예방하기 위함입니다.

이를 위해 Looper Handler 두 클레스를 제공합니다.


Looper 와 Handler 를 이용한 UI 스레드와의 통신

스레드는 Handler 클래스를 이용해 Message를 Message Queue에 넣고

UI 스레드에서는 Looper를 이용해서 Message Queue에 접근해

다른 스레드에서 보내는 데이터를 처리합니다.


Handler(message) -> Message Queue <- Looper <- UI Thread

                 보내고                                   받고

* 스레드가 Handler 객체를 생성하는 것이 아니고 Handler 객체가 스레드를 생성.


AsyncTask 에 RxAndroid 적용

AsyncTask

안드로이드에서 제공하는 추상 클래스.

안드로이드의 대표 스레드.

별도의 Handler나 스레드 사용 없이 UI 스레드에서

백그라운드 작업을 수행하고, 결과를 바로  View 화면에 업데이트.


예제)

package park.sunggyun.thomas.rxandroidex;

import android.os.AsyncTask;
import android.util.Log;

public class Examples extends AsyncTask<String, Void, String> {

private void init() {
Examples examples = new Examples();
examples.execute("Hello", "Rx", "Android");
}

@Override
protected String doInBackground(String... strings) {
StringBuilder stringBuilder = new StringBuilder();
for (String str : strings) {
stringBuilder.append(str).append(" ");
}
return stringBuilder.toString();
}

@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.e("append", "str successfully");
}
}

Log.e 대신에 UI를 업데이트하는 예제로 바꾸시면 되겠습니다.

가령 textView.setText(s); 처럼요.


RxAndroid로 구현하기.

package park.sunggyun.thomas.rxandroidex;


import android.util.Log;

import io.reactivex.MaybeObserver;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

public class RxAsync {

private void init() {
Observable.just("hello", "Rx", "Android")
.reduce((x, y) -> x + "" + y) // Async 예제의 StringBuilder 의 append 역할.
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
d -> Log.d("getStr", d),
e -> Log.e("getError", e.getMessage()),
() -> Log.i("getComplete", "done")
);

Observable.just("hello", "Rx", "Android")
.reduce((x, y) -> x + "" + y) // Async 예제의 StringBuilder 의 append 역할.
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver());


}

private MaybeObserver<String> getObserver() {
return new MaybeObserver<String>() {
@Override
public void onSubscribe(Disposable d) {

}

@Override
public void onSuccess(String s) {
Log.d("getStr", s);
}

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

@Override
public void onComplete() {
Log.i("getComplete", "done");
}
};
}

}

RxAndroid 바꿔본 예제 인데요.

함수를 별도로 생성해서 아래 Observable처럼 해도되고

위 Observable처럼 해도 됩니다.

observeOn(AndroidSchedulers.mainThread()) 는

구독자가 실행하게될 스레드를 안드로이드의 UI 스레드로 지정합니다.


위 두 예제를 통한 기능의 비교

AsyncTask              RxAndroid

excute()                 subscribe()

doInBackground()    리액티브 연산자와 함께 사용하는 onSubscribe()

onPostExecuted()     observer

정확한 비교는 아니지는 비슷한 기능을 합니다.


다음 포스팅에서는 TimerTask를 RxAndroid로 바꿔보겠습니다.

이상입니다. 감사합니다. 


반응형