일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 주택가 잠실새내
- 2022년 6월 일상
- 막내의막무가내 코틀린
- Fragment
- 프로그래머스 알고리즘
- 막내의 막무가내 알고리즘
- 막내의막무가내 SQL
- 막내의막무가내 rxjava
- flutter network call
- 막내의 막무가내
- 막내의막무가내 안드로이드 에러 해결
- 안드로이드
- 막내의막무가내 플러터
- 막내의막무가내 목표 및 회고
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 알고리즘
- 막내의막무가내 안드로이드
- 부스트코스에이스
- 막무가내
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 안드로이드 코틀린
- 막내의막무가내 플러터 flutter
- 막내의막무가내
- 안드로이드 Sunflower 스터디
- 막내의막무가내 일상
- 안드로이드 sunflower
- 막내의막무가내 프로그래밍
- 부스트코스
- 프래그먼트
- 주엽역 생활맥주
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[RxJava] Observable 클래스 본문
rajava 프로그래밍 책을 읽으면서 공부중입니다. 시간이 부족해 매번 같은 곳만 보고 있네요... 간략히 정리좀 해볼려고합니다.
제목은 말 그대로 옵서버 패턴을 구현한 클래스입니다. 옵서버 패턴은 객체의 상태 변화를 관찰하는 옵서버 목록을 객체에 등록합니다.
Observable 클래스를 통해 데이터 발행 이벤트를 추가하고 subscribe() 함수를 통해 Observable을 구독하면 그 때부터 구독자에게 데이터가 발행되기 시작합니다.
옵서버 패턴은 유튜버와 구독자의 개념으로 보면 이해하기 쉽습니다. 구독자가 유튜버 채널을 구독하면 유튜버가 영상을 올릴 때마다 구독자에게 알림이 가서 알 수 있습니다.
[알림 이벤트]
Observable은 3가지 알림 메소드가 있습니다.
onNext : Observable 데이터의 발행을 알립니다.
onComplete: 모든 데이터가 발행됬음을 알립니다. 한번만 호출되며 모든 데이터가 발행됬으므로 onNext 이벤트가 발생하지 않습니다.
onError : Observable에 에러가 발생했음을 알립니다. 이 이후에는 onNext, onComplete 이벤트가 발생하지 않고 Observable 실행이 종료됩니다.
[발행 이벤트]
just() : 넣는 순서대로 그냥 발행합니다. 가장 기본적인 구조입니다.
Observable.just(1,2,3,4)
.subscribe(System.out::println)
1
2
3
4
create() : 함수에 데이터를 넣으면 자동으로 알림 이벤트가 발생하는 just() 와 달리 onNext, onComplete, onError 같은 알림을 개발자가 직접 호출합니다.
Observable.create<String> { emitter ->
emitter.onNext("1")
emitter.onNext("2")
emitter.onNext("3")
emitter.onComplete()
}.subscribe({
Log.d("onNext", it.toString())
}, {
Log.d("onError", it.message)
}, {
Log.d("onComplete", "Complete")
})
Observable<String> source = Observable.create(
(ObservableEmitter<String> emitter) -> {
emitter.onNext("1")
emitter.onNext("2")
emitter.onNext("3")
emitter.onComplete()
});
source.subscribe(data -> Lod.d("data", data))
fromArray() : just(), create() 와 달리 배열 데이터를 처리할 때 사용합니다.
fromIterable() : Iterable 인터페이스를 구현한 클래스 데이터를 처리할 때 사용합니다. 대표적으로 ArrayList, HashSet, LinkedList, TreeSet, Vector 등이 있습니다.
fromCallable() : 비동기 작업에 사용됩니다. 자바 5에서 추가된 동시성 API인 Callable 인터페이스 객체와 함께 사용됩니다. (비동기 클래스)
Callable<String> callable = ()->{
Thread.sleep(1000);
return "Hello Callable";
};
Observable<String> source=Observable.fromCallable(callable);
source.subscribe(System.out::println);
//출력 Hello Callable
fromFuture() : 마찬가지로 자바 5에서 추가된 동시성 API 중 하나인 Future 인터페이스 객체와 함께 사용한다는데 실제 사용법은 아직 잘 모르겠습니다. 뒤에서 스케줄러와 함께 활용되는 경우가 많다는데 나중에 보도록 합니다. fromCallable() 과 다른점은 반환된 Future 객체에 get() 메서드를 호출하면 결괏값이 나올 때까지 기다린다는 점만 짚고 넘어갑니다.
[구독관련]
subscirbe() : Rxjava는 내가 동작시키기 원하는 것을 사전에 정의 후 실제 그것이 실행되는 시점을 subscribe() 함수를 통해 조절할 수 있습니다. 위으 just() 함수의 경우에도 팩토리 함수로 구현되어 데이터 흐름을 정의 한 후 subscribe() 함수를 호출해야 데이터가 발행됩니다.
Disposable : subscribe() 는 Disposable 이라는 인터페이스 객체를 반환합니다. 이것은 구독 객체에 해당되며 다음과 같은 함수를 갖고 있습니다.
void dispose()
=> Observable에게 더이상 데이터를 발행하지 않도록 구독을 해지합니다.
=> Observable이 onComplete 알림을 보내면 자동으로 이 함수가 호출되 구독을 해지해줍니다.
boolean isDisposed()
=> 말그대로 구독이 해지되었는지(데이터 발행하지 않는지) 확인하는 함수입니다.
[커니의 코틀린 RxJava Retrofit2 예제코드]
package com.androidhuman.example.simplegithub.ui.repo
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import com.androidhuman.example.simplegithub.R
import com.androidhuman.example.simplegithub.api.provideGithubApi
import com.androidhuman.example.simplegithub.extensions.plusAssign
import com.androidhuman.example.simplegithub.ui.GlideApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_repository.*
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Locale
class RepositoryActivity : AppCompatActivity() {
companion object {
const val KEY_USER_LOGIN = "user_login"
const val KEY_REPO_NAME = "repo_name"
}
internal val api by lazy { provideGithubApi(this) }
internal val disposables = CompositeDisposable()
internal val dateFormatInResponse = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssX", Locale.getDefault())
internal val dateFormatToShow = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_repository)
val login = intent.getStringExtra(KEY_USER_LOGIN) ?: throw IllegalArgumentException(
"No login info exists in extras")
val repo = intent.getStringExtra(KEY_REPO_NAME) ?: throw IllegalArgumentException(
"No repo info exists in extras")
showRepositoryInfo(login, repo)
}
override fun onStop() {
super.onStop()
disposables.clear()
}
private fun showRepositoryInfo(login: String, repoName: String) {
disposables += api.getRepository(login, repoName)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { showProgress() }
.doOnError { hideProgress(false) }
.doOnComplete { hideProgress(true) }
.subscribe({ repo ->
GlideApp.with(this@RepositoryActivity)
.load(repo.owner.avatarUrl)
.into(ivActivityRepositoryProfile)
tvActivityRepositoryName.text = repo.fullName
tvActivityRepositoryStars.text = resources
.getQuantityString(R.plurals.star, repo.stars, repo.stars)
if (null == repo.description) {
tvActivityRepositoryDescription.setText(R.string.no_description_provided)
} else {
tvActivityRepositoryDescription.text = repo.description
}
if (null == repo.language) {
tvActivityRepositoryLanguage.setText(R.string.no_language_specified)
} else {
tvActivityRepositoryLanguage.text = repo.language
}
try {
val lastUpdate = dateFormatInResponse.parse(repo.updatedAt)
tvActivityRepositoryLastUpdate.text = dateFormatToShow.format(lastUpdate)
} catch (e: ParseException) {
tvActivityRepositoryLastUpdate.text = getString(R.string.unknown)
}
}) {
showError(it.message)
}
}
private fun showProgress() {
llActivityRepositoryContent.visibility = View.GONE
pbActivityRepository.visibility = View.VISIBLE
}
private fun hideProgress(isSucceed: Boolean) {
llActivityRepositoryContent.visibility = if (isSucceed) View.VISIBLE else View.GONE
pbActivityRepository.visibility = View.GONE
}
private fun showError(message: String?) {
with(tvActivityRepositoryMessage) {
text = message ?: "Unexpected error."
visibility = View.VISIBLE
}
}
}
'안드로이드 > RxJava' 카테고리의 다른 글
[RxJava] RxJava 프로그래밍 책 후기 (6) | 2020.09.03 |
---|---|
[RxJava] Convert Observable to Single (Single.fromObservable) + flatMapCompletable (0) | 2020.05.21 |
[RxJava] MVVM - Model Layer 네트워크 통신에 적용 (4) | 2020.05.12 |
[RxJava] 기초 개념 정리 사이트 (0) | 2020.05.08 |
[RxJava] RxJava 리엑티브 프로그래밍 공부 정리 (0) | 2020.03.17 |