ReactiveX

RxPermissions, RxBinding 라이브러리

smomo 2021. 8. 17. 20:33

1. RxPermissions Library

RxJava에서 제공하는 Android 런타임 권한 라이브러리(Beta 버전)

  • Dependencies
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.12'
}
  • 사용법(Kotlin)
val rxPermissions = RxPermissions(this) // where this is an Activity or Fragment instance

Frament에서 RxPermissions를 사용하는 경우 RxPermissions (fragment.getActivity ()) 대신 프래그먼트 인스턴스 (RxPermissions (this))를 전달해야 한다. 그렇지 않으면 java.lang.IllegalStateException이 발생할 수 있다.

 

  • Example
// onCreate와 같은 초기화 단계에서 수행해야한다
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) { 
           // 
        } else {
           // permission denied
        }
    });

동시에 여러 권한이 있을 경우

rxPermissions
    .request(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(granted -> {
        if (granted) {
           // 모든 권한이 승인
        } else {
           // 하나 이상의 권한이 거부
        }
    });

requestEach 또는 ensureEach로 자세한 결과를 관찰 가능

rxPermissions
    .requestEach(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(permission -> { // 2개의 권한 개체 subscribe
        if (permission.granted) {
           // `permission.name` is granted !
        } else if (permission.shouldShowRequestPermissionRationale) {
           // Denied permission without ask never again
        } else {
           // Denied permission with ask never again
           // 설정으로 이동
        }
    });

2. RxBinding Library

Android UI 위젯용 RxJava 바인딩 라이브러리

  • Dependencies
//Platform bindings
implementation 'com.jakewharton.rxbinding4:rxbinding:4.0.0'

//AndroidX library bindings
implementation 'com.jakewharton.rxbinding4:rxbinding-core:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-appcompat:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-drawerlayout:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-leanback:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-recyclerview:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-slidingpanelayout:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-swiperefreshlayout:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-viewpager:4.0.0'
implementation 'com.jakewharton.rxbinding4:rxbinding-viewpager2:4.0.0'

//Google 'material' library bindings
implementation 'com.jakewharton.rxbinding4:rxbinding-material:4.0.0'

2-1 UI Event Binding

onClicks

view를 클릭할 때 사용하는 UI 이벤트

  • Java
Observable observable = RxView.clicks(button);
observable.subscribe(it -> Toast.makeText(mContext, "clicked!!", Toast.LENGTH_SHORT).show());
  • Kotlin
val click = view.findViewById<Button>(R.id.click_button)
click.clicks()
     .subscribe {
     	Toast.makeText(context, "clicked!!", Toast.LENGTH_SHORT).show()
     }

Viewpager2

  • Kotlin
viewpager.pageSelections()
         .subscribe {
            Log.d(TAG, "pageSelected page = $it")
         }
viewpager.pageScrollEvents()
         .subscribe {
            Log.d(TAG, "PageScrollEvent position = ${it.position}, positionOffset = ${it.positionOffset}")
        }

3. RxBinding + RxPermission Example

  • Java
// Must be done during an initialization phase like onCreate
RxView.clicks(findViewById(R.id.enableCamera))
    .compose(rxPermissions.ensure(Manifest.permission.CAMERA))
    .subscribe(granted -> {
        // R.id.enableCamera has been clicked
    });
  • Kotlin
val enableCamera = view.findViewById<View>(R.id.enable_camera)
enableCamera.clicks()
    .compose(rxPermissions.ensure(Manifest.permission.CAMERA))
    .subscribe(
        Consumer<Permission>() {
        	if (it.granted) {

          	} else if (it.shouldShowRequestPermissionRationale) {

          	} else {

          	}
        },
        Consumer<Throwable>() {
        	Log.e(TAG,"onError", it)
        },
        Action {
        	Log.i(TAG,"onComplete")
        }
    )

4. Android memory leaks

subscribe 함수 호출 시 반환되는 disposable을 CompositeDisposable객체에 담아두고 한번에 해제시킨다.

class MainActivity :AppCompatActivity(){
    private var disposables = CompositeDisposable()
    	....
    
    override fun onCreate(savedInstanceState: Bundle?) {
    	...
    	val disposable1 = viewpager.pageSelections()
                .subscribe {
                    Log.d(TAG, "pageSelected page = $it")
                }
        disposables.add(disposable1)
    }
    
	override fun onStop() {
        super.onStop()
        if(disposables.size() > 0){
            disposables.clear()
        }
    }
}

References