본문 바로가기
Rx

안드로이드의 RxJava 활용 - 4( 액티비티 중복 실행 문제)

by 봄석 2018. 12. 30.

본 내용은 필자가 학습한 내용을 정리하는 내용입니다.

대부분 의 내용이 아래 책의 내용이므로 원서를 구매해서 직접보시는걸 추천드립니다!

RxJava 프로그래밍 리액티브 프로그래밍 기초부터 RxAndroid까지 한 번에

유동환 , 박정준 지음 | 한빛미디어 | 2017년 09월 04일 출간

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788968488658&orderClick=LAV&Kc=


저자님의 블로그

https://brunch.co.kr/@yudong#info



액티비티 중복실행 문제 해결하기

현업에서 자주 발생하는 액티비티 중복 실행 문제를 간단하게 해결할 수 있는 코드입니다.

public class DebounceFragment extends Fragment {
 
    @BindView(R.id.btn_debounce) Button mButton;
    @BindView(R.id.tv_display) TextView mDisplay;
 
    Unbinder mUnbinder;
    Disposable mDisposable;
 
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View layout =  inflater.inflate(R.layout.fragment_debounce, container, false);
        mUnbinder = ButterKnife.bind(this, layout);
        return layout;
    }
 
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mUnbinder != null) {
            mUnbinder.unbind();
        }
        mDisposable.dispose();
    }
 
 
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
 
        mDisposable = getObservable()
                .debounce(1000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> {
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss", Locale.KOREA);
                    String time = sdf.format(Calendar.getInstance().getTime());
                    mDisplay.setText("Clicked : " + time.toString());
                });
 
    }
 
    private Observable<View> getObservable() {
        return Observable.create(e ->  mButton.setOnClickListener(e::onNext));
    }
}




액티비티 중복 실행 문제는 안드로이드 SDK의 제약 사항이기도 합니다. 빠른 시간 안에 액티비티의 실행을 다시 요청하면 SingleTop의 경우에도 액티비티는 중복 실행됩니다. RxAndroid에서는 debounce() 함수를 이용하여 쉽세 이문제를 해결할 수 있습니다



-------------------------------------------------------------------------------------------------------출처 -https://medium.com/@progjh/throttle-debounce-%EA%B0%9C%EB%85%90-%EC%9E%A1%EA%B8%B0-19cea2e85a9f


debounce() 알아보기

어떤 기술의 핵심을 이해하는데 가장 좋은 방법은 해당 기술이 나온 이유를 먼저 아는것이라고 생각한다!

스크롤을 이벤트가 발생할때 마다 호출되는 콜백이 있다고 가정해보자. 우리는 잘 못느낄 수 있으나 사실 스크롤을 한번 드르륵 해주기만 해도 수많은 스크롤 이벤트가 발생하게 된다.

이런 스크롤 이벤트에 매번 콜백이 발생한다면? 그리고 그 콜백이 수행하는 일이 매우 큰 리소스를 먹는 작업이라면?

상상하기 싫다. Throttle 과 Debounce 는 이렇게 이벤트가 과도한 횟수로 발생하는 것에 제약을 걸어 제어할 수 있는 수준으로 이벤트를 발생시키는 것을 목표로 한다.


Throttle

이벤트를 일정한 주기마다 발생하도록 하는 기술이다. 예를 들어 Throttle 의 설정시간으로 1 ms 를 주게되면 해당 이벤트는 1ms 동안 최대 한번만 발생하게 된다. 위의 Throttle 기법이 적용될 경우 다음과 같이 작동하게 된다.

설정시간 = 1ms

일반 : 이벤트1 이벤트2 이벤트3 이벤트4
Throttle 예제 : 이벤트1 ( — 1ms —) 이벤트2 ( — 1ms — ) 이벤트3

Debounce

이벤트를 그룹화하여 특정시간이 지난 후 하나의 이벤트만 발생하도록 하는 기술이다. 말이 어려우므로 바로 예시를 통해 이해해보자.

설정시간 = 5ms

일반 : 이벤트이벤트이벤트이벤트이벤트

Debounce 예제 1 : 이벤트1 이벤트2 ( —5ms — )

→ 이벤트2발생!

Debounce 예제 2 : 이벤트1 이벤트2 (— 4.9ms— ) 이벤트4 이벤트5(— 5ms — )

→ 이벤트6발생!

Throttle과 차이를 알겠는가?

Debounce는 아무리 많은 이벤트가 발생해도 모두 무시하고 특정 시간사이에 어떤 이벤트도 발생하지 않았을 때 딱 한번만 마지막 이벤트를 발생시키는 기법이다.

따라서 5ms 가 지나기전에 계속 이벤트가 발생할 경우 콜백에 반응하는 이벤트는 발생하지 않고 계속 무시된다. 예제 2에서는 실제로 6개의 이벤트가 발생했음에도 불구하고 실제로 콜백이 반응하는 이벤트는 ‘이벤트 6’ 단 하나뿐이다.

Debounce 는 검색기능을 구현할 때 매우 유용하게 사용할 수 있다.

EditText 에서 내용이 바뀔때마다 해당 내용을 검색하는 API 를 날린다고 가정해보자. ‘자바’를 검색한다고 했을 때 아무런 처리도 하지않을 경우 EditText 리스너는 모든 변화를 캐치하여 (ㅈ), (자), (자ㅂ), (자바) 총 4번의 API를 날릴 것이다.

사실 사용자가 검색하고싶은 내용은 ‘자바’라는 내용이므로 이전 내용의 검색결과는 아무 쓸모가 없으며, 해당 검색결과를 계속 그려주는 리소스낭비도 매우 심할 것이다.

만약 여기에 Debounce (500ms)를 적용할 경우 다음과 같이 작동시킬 수 있다.

Debounce 예제 3 :
‘ㅈ’ ( — 300ms — ) ‘자’ ( — 250ms — ) ‘자ㅂ’ (— 310ms— ) ‘자바’ ( — 500ms — )
 → ‘자바’라는 내용으로 한번만 검색 API 를 호출!




댓글