MVVM com RxJava com Kotlin
-
Upload
gdgfoz -
Category
Technology
-
view
82 -
download
2
Transcript of MVVM com RxJava com Kotlin
![Page 1: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/1.jpg)
MVVM com RxJava em Kotlin no Android
![Page 2: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/2.jpg)
GDGFoz
Quem ?• Houssan Ali Hijazi - [email protected]
• Desenvolvedor Android na www.HElabs.com
• Organizador GDG Foz do Iguaçu
• www.lojasnoparaguai.com.br
• www.desaparecidosbr.org
• www.hussan.com.br
![Page 3: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/3.jpg)
GDGFoz
Kotlin
• 2011/JetBrains
• 1.0 em Fev. 2016
• 1.1 em Mar. 2017
• Pinterest, Coursera, Netflix, Uber, Square, Trello e Basecamp
• 17/Maio - Google IO 2017
![Page 4: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/4.jpg)
GDGFoz
Kotlin
• Interoperabilidade
• Null Safety
• Conciso
![Page 5: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/5.jpg)
GDGFoz
Manifesto reativo
• Responsivo - Reagir rápido
• Resiliente - Reagir a falhas
• Elástico - Reagir a carga / Autoescalar
• Orientado a mensagens - Comunicação assíncrona
Fonte: https://www.reactivemanifesto.org/pt-BR
![Page 6: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/6.jpg)
GDGFoz
RxJava
• RxJava - Reactive Extensions para a JVM - uma
biblioteca para compor programas assíncronos e
baseados em eventos usando sequências
observáveis.
• Netflix
• 1.0.0 em 18 Nov 2014
• 2.0.0 em 28 Out 2016
![Page 7: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/7.jpg)
GDGFoz
RxJava
Observable
Disposable
subscribe(Observer<T>)
Emite
Observer
onNext(T)
onComplete()
onError(Throwable)Consome
![Page 8: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/8.jpg)
GDGFoz
RxJava
• Observable - Emite dados
• Observer - Consome dados
• Disposable
• Operators: map, flatmap, filter, last, first etc..
• Schedulers
![Page 9: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/9.jpg)
GDGFoz
Código
• Robusto
• Estável
• Testável
• Modular
![Page 10: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/10.jpg)
GDGFoz
Model/View/Controller
Activity
IView
![Page 11: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/11.jpg)
GDGFoz
Model/View/Presenter
Contract
![Page 12: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/12.jpg)
GDGFoz
App
![Page 13: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/13.jpg)
GDGFoz
Model/View/Presenter// View contract
interface RepositoriesContract{
interface View{
fun setRepositories(repositories: List<Repository>)
}
}
// Activity/Fragment
class RepositoriesActivity : AppCompatActivity(), RepositoriesContract.View {
...
// Passing the View to Presenter
presenter = RepositoriesPresenter(this)
override fun setRepositories(repositories: List<Repository>) {
// Setting data to view
}
![Page 14: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/14.jpg)
GDGFoz
Model/View/Presenter// Presenter contract
interface RepositoriesContract {
interface Presenter {
fun getAllRepositories()
}
}
// Passing View to Presenter
class RepositoriesPresenter(val view: RepositoriesContract.View): RepositoriesContract.Presenter
lateinit var model: RepositoryModel
override fun getAllRepositories() {
// Call model and set data to View
// Can be RxJava
var repositories:List<Repository> = model.getAllRepositories()
view.setRepositories(repositories)
}
![Page 15: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/15.jpg)
GDGFoz
Model/View/ViewModel
• Microsoft
• 2005
• Orientado à eventos
![Page 16: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/16.jpg)
GDGFoz
Model/View/ViewModel
![Page 17: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/17.jpg)
GDGFoz
MVVM// ViewModelclass RepositoriesViewModel(var model: RepositoryDataSource) {
...
fun getAllRepositories() {
// Return an Observable
fun getAllRepositories(): Observable<List<Repository>> = model.getAllRepositories()
}
![Page 18: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/18.jpg)
GDGFoz
MVVM// Activity/Fragment
class RepositoriesActivity : AppCompatActivity() {
private val viewModel: RepositoriesViewModel by lazy {RepositoriesViewModel(RepositoryModel())
}
private val mDisposable = CompositeDisposable()...
![Page 19: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/19.jpg)
GDGFoz
MVVM
// Activity/Fragment
override fun onCreate(savedInstanceState: Bundle?) {
...
mDisposable.add(
viewModel.getAllRepositories()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
// onNext
this::setRepositories,
// onError
{ error -> Log.d(TAG, "Error: ", error) },
// onComplete
{ Log.d(TAG, "Completed: ") }
)
)
// Activity/Fragment
fun setRepositories(repositories: List<Repository>) {
// Setting data to view
}
![Page 20: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/20.jpg)
GDGFoz
Android lifecycle
// Activity/Fragment
override fun onDestroy() {
super.onDestroy()
mDisposable.dispose()
}
![Page 21: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/21.jpg)
GDGFoz
MVP/MVVMclass Presenter: IPresenter {
override fun getAllRepositories() {
...
view.setRepositories(repositories)
}
}
class ViewModel {
fun getAllRepositories(): Observable<List<Repository>> {
...
}
}
![Page 22: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/22.jpg)
GDGFoz
MVVM testsclass RepositoriesViewModelTest {
@Mock
lateinit var model: RepositoryDataSource
lateinit var viewModel: RepositoriesViewModel
…
@Before
fun setup()
{
model = mock()
viewModel = RepositoriesViewModel(model)
}
![Page 23: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/23.jpg)
GDGFoz
MVVM tests@Test
fun `get repositories emit correct values`() {
val repositories = listOf(Repository(name = "Test"), Repository(name = "Test2"
`when`(model.getAllRepositories()).thenReturn(Observable.just(repositories))
viewModel.getAllRepositories()
.test()
.assertNoErrors()
.assertComplete()
.assertValue(repositories)
}
![Page 24: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/24.jpg)
GDGFoz
Save states
// Save
override fun onSaveInstanceState(state: Bundle?) {
super.onSaveInstanceState(state)
//Can create Bundle here
state.putAll(viewModel.getState())
}
// Restore
override fun onRestoreInstanceState(bundle: Bundle) {
super.onRestoreInstanceState(bundle)
viewModel.restoreState(bundle)
}
![Page 25: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/25.jpg)
GDGFoz
Activity
Fragment
CustomView
CustomView
P / VM
View
![Page 26: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/26.jpg)
GDGFoz
Lógica de UI ?
• Tem lógica de UI ?
• Sim - Presenter/ViewModel (Testes)
• Não - View
![Page 27: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/27.jpg)
GDGFoz
Qual ?
• Classes Android sem lógica ?
• Pode ser testado (unit test) ?
• Suas classes tem uma responsabilidade bem definida ?
![Page 28: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/28.jpg)
GDGFoz
Links
• http://reactivex.io/
• https://github.com/ReactiveX/RxJava/
• https://kotlinlang.org/
• https://medium.com/upday-devs/android-architecture-patterns-part-3-model-view-viewmodel-e7eeee76b73b
• https://github.com/googlesamples/android-architecture
• https://github.com/hussanhijazi/retrofit-rxjava-databinding/tree/kotlin-mvvm
![Page 29: MVVM com RxJava com Kotlin](https://reader036.fdocumentos.com/reader036/viewer/2022082213/5a65e5a77f8b9a21248b49e5/html5/thumbnails/29.jpg)
Obrigado