SlideShare a Scribd company logo
1 of 76
Download to read offline
KimKevin
Android Developer / Kakaobank
Android Jetpack

ViewModel and Testing
ViewModel
Model
Presenter
View
Repository
The past of past
Model
ViewModel

(Not AAC)
Presenter
Repository
View
Databinding
The past
Model
AAC ViewModel
Repository
View
Databinding
The present
ViewModel
! The Lifecycle Library’s ViewModel class

! android.arch.lifecycle -> androidx.lifecycle

! Provides data for UI components and survive configuration changes.
ViewModel can help
! Avoiding memory leaks

! Solving common Android lifecycle challenges
ViewModel can help
! Avoiding memory leaks

! Solving common Android lifecycle challenges

! Share data between fragments
class UserViewModel : ViewModel() {
val name = MutableLiveData<String>()
}
class UserFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
val userViewModel =
ViewModelProviders.of(getActivity()).get(UserViewModel::class.java)
loginButton.setOnClickListener({ item -> userViewModel.name = item })
}
}
class UserProfileFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
val userViewModel =
ViewModelProviders.of(getActivity()).get(UserViewModel::class.java)
userViewModel.name.observe(this, { name ->
// Update the UI.
})
}
}
ViewModel can help
! Avoiding memory leaks

! Solving common Android lifecycle challenges

! Share data between fragments

! Design good software (SRP, testing etc)
Activity
Activity
Data Loading
Drawing UI
Components
Processing Data
Handling all UI
Interactions
Saving and
restoring the UI
Data Loading
Drawing UI
Components
Processing Data
Handling all UI
Interactions
Saving and
restoring the UI
Activity
Activity
https://stackify.com/solid-design-principles
Data Loading
Drawing UI
Components
Processing Data
Handling all UI
Interactions
Saving and
restoring the UI
Activity
Activity
Single Responsibility Principle
https://stackify.com/solid-design-principles
Activity

Drawing UI

Receiving User Interactions
as Android Developer
Activity

Drawing UI

Receiving User Interactions
ViewModel

Hold UI Data
Repository

API for saving and loading app data
Presenter

Process data for UI
User Case

full fledged clean architecture
And more…
as Android Developer
as Java Developer
Activity

Drawing UI

Receiving User Interactions
ViewModel

Hold UI Data
Repository

API for saving and loading app data
Presenter

Process data for UI
User Case

full fledged clean architecture
And more…
as Android Developer
as Java Developer
Provides

APIs
Testable
Code
Reactive UI
! ViewModel

! LiveData

! Data Binding 

! Android Studio 3.1 +

! Support for ViewModel and LiveData

! setLifecycleOwner(LifecycleOwner)
ViewModel could do
! Handle configuration changes

! Replace onSaveInstanceState()
Activity Instance
Activity UI data
Activity Instance
RotationEvent
Activity UI data
Activity Instance
Recreated Activity

Instance
RotationEvent
Forgotten data that didn’t get passed to next activity
Activity UI data
<activity android:name="MainActivity"
android:configChanges="screenSize|orientation" />
Activity
Fragment
public void onCreate(@Nullable Bundle savedInstanceState) {
···
setRetainInstance(true)
}
ViewModel
Activity Instance
Activity UI data
ViewModel
Activity UI data
RotationEvent
Activity Instance
ViewModel
Activity UI data
Activity Instance
Recreated Activity

Instance
RotationEvent
class UserLoginViewModel : ViewModel() {
private val _id = MutableLiveData<String>()
val id: LiveData<String>
get() = _id
private val _password = MutableLiveData<String>()
val password: LiveData<String>
get() = _password
···
}
public abstract class ViewModel {
@SuppressWarnings("WeakerAccess")
protected void onCleared() { }
}
public abstract class ViewModel {
@SuppressWarnings("WeakerAccess")
protected void onCleared() { }
}
@Override
protected void onDestroy() {
super.onDestroy();
···
mViewModelStore.clear();
···
}
FragmentActivity & Fragment
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
@Override
protected void onDestroy() {
super.onDestroy();
···
mViewModelStore.clear();
···
}
FragmentActivity & Fragment
ViewModelStore
WARNING!
! Don’t store Contexts in a ViewModel

! Activities, Fragments, Views, etc
ViewModel
Activity UI data
Activity Instance
If you store an
Activity
ViewModel
Activity UI data
Activity Instance
If you store an
Activity
RotationEvent
ViewModel
Activity UI data
Activity Instance
If you store an
Activity
RotationEvent
Recreated Activity

Instance
MEMORY LEAK
override fun onCreate(savedInstanceState: Bundle?) {
···
val userLoginViewModel =
ViewModelProviders.of(this, factory).get(UserLoginViewModel::class.java)
}
ViewModelProdivers.of() creates a ViewModelProvider
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(activity.getViewModelStore(), factory);
}
override fun onCreate(savedInstanceState: Bundle?) {
···
val userLoginViewModel =
ViewModelProviders.of(this, factory).get(UserLoginViewModel::class.java)
}
ViewModelProviders
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
// Lifecycles 2.0.0-alpha1 (AndroidX)
return new ViewModelProvider(activity.getViewModelStore(), factory);
// Lifecycles 1.1.1
return new ViewModelProvider(ViewModelStores.of(activity), factory);
}
ViewModelProviders
public static ViewModelStore of(@NonNull FragmentActivity activity) {
if (activity instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) activity).getViewModelStore();
}
return holderFragmentFor(activity).getViewModelStore();
}
public HolderFragment() {
setRetainInstance(true);
}
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
···
return new ViewModelProvider(ViewModelStores.of(activity), factory);
}
ViewModelStores (Not included in AndroidX)
ViewModelProviders
Lifecycles 1.1.1
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
···
return new ViewModelProvider(activity.getViewModelStore(), factory);
}
public static ViewModelProvider of(@NonNull Fragment fragment,
@Nullable Factory factory) {
···
return new ViewModelProvider(fragment.getViewModelStore(), factory);
}
// for FragmentActivity
Lifecycles 2.0.0-alpha1 (AndroidX)
ViewModelProviders
// for Fragment
ViewModelStore

ViewModel2
FragmentA

ViewModel3
ViewModelStore

ViewModel1
ViewModel1
FragmentB

ViewModel2
Created FragmentActivity
ViewModelStore

ViewModel2
FragmentA

ViewModel3
ViewModelStore

ViewModel1
FragmentB

Recreated FragmentActivity on rotation
ViewModelStore

ViewModel2
FragmentA

ViewModel3
ViewModelStore

ViewModel1
ViewModel1
ViewModelProvider
ViewModelProviders
FragmentB

ViewModel2
Restored ViewModels
ViewModelStore

ViewModel2
ViewModel3
ViewModelStore

ViewModel1
FragmentA

ViewModel1
ViewModelProvider
ViewModelProviders
FragmentB

ViewModel2
Restored ViewModels
ViewModelStore

ViewModel2
ViewModel3
ViewModelStore

ViewModel1
How to restore ViewModelStore
@Override
public final Object onRetainNonConfigurationInstance() {
···
Object custom = onRetainCustomNonConfigurationInstance();
FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
if (fragments == null && mViewModelStore == null && custom == null) {
return null;
}
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = mViewModelStore;
nci.fragments = fragments;
return nci;
}
FragmentActivity Retain All fragment state
FragmentActivity Restore All fragment state
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
···
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
···
}
FragmentActivity Restore All fragment state
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
···
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
···
}
Restore All fragment state
public void restoreAllState(Parcelable state, FragmentManagerNonConfig
nonConfig) {
mHost.mFragmentManager.restoreAllState(state, nonConfig);
}
FragmentController
Restore All fragment state
FragmentController
public void restoreAllState(Parcelable state, FragmentManagerNonConfig
nonConfig) {
mHost.mFragmentManager.restoreAllState(state, nonConfig);
}
FragmentManager
void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
···
if (nonConfig != null) {
List<Fragment> nonConfigFragments = nonConfig.getFragments();
childNonConfigs = nonConfig.getChildNonConfigs();
viewModelStores = nonConfig.getViewModelStores();
···
mActive = new SparseArray<>(fms.mActive.length);
for (int i=0; i<fms.mActive.length; i++) {
FragmentState fs = fms.mActive[i];
if (fs != null) {
FragmentManagerNonConfig childNonConfig = null;
if (childNonConfigs != null && i < childNonConfigs.size()) {
childNonConfig = childNonConfigs.get(i);
}
ViewModelStore viewModelStore = null;
if (viewModelStores != null && i < viewModelStores.size()) {
viewModelStore = viewModelStores.get(i);
}
Fragment f = fs.instantiate(mHost, mContainer, mParent,
childNonConfig, viewModelStore);
Restore All fragment state
ViewModel could do
! Handle configuration changes?
ViewModel could do
! Handle configuration changes? Yes!
ViewModel could do
! Handle configuration changes? Yes!

! Replace onSaveInstanceState()?
ViewModel could do
! Handle configuration changes? Yes!

! Replace onSaveInstanceState()? No!
Use ViewModel with onSaveInstanceState
• Survives configuration changes

• Hold lots of data
• Survives configuration changes and process death

• Requires serialization

• Hold small amount of data (less than 50k of data)
All data for Activity UI
Data to reload Activity data

in emergency
ViewModel onSaveInstanceState
Use ViewModel with onSaveInstanceState
• Survives configuration changes

• Hold lots of data
• Survives configuration changes and process death

• Requires serialization

• Hold small amount of data (less than 50k of data)
All the user’s data:

User id, first name, last name, birthday,

address, profile images…
User id
ViewModel onSaveInstanceState
and Testing
https://github.com/mockito/mockito/issues/1013
Wiki & Docs
How to use Search feature
• Handling network errors
• ERROR CODE : 1003
• Do something!
•
•
Wiki & Docs
How to use Search feature
• Handling network errors
• ERROR CODE : 1003
• Do something!
•
•
Hard to keep document the latest,

whenever requirement changes
Why writing Unit tests
! Think of unit tests as documentation for future developers

! Help developers to refactor safely
https://www.shutterstock.com
Testing is 

not only for you

but also for your colleagues in your next seat
Presenter Testing
! Behavior Driven Testing

! Template : Given-When-Then (3A - Arrange-Act-Assert)
@Test
fun givenErrorCode1003_whenSearch_shouldHandleError() {
val networkError = NetworkException(1003, "Network Error!")
doThrow(networkError).when(mockSearchRepository).search(INVALID_QUERY)
presenter.search(INVALID_QUERY)
verify(view).hideLoading()
verify(view).setErrorMessage(networkError.message)
}
ViewModel Testing
! Assert data values
@Test
fun givenErrorCode1003_whenSearch_shouldHandleError() {
val networkError = NetworkException(1003, "Network Error!")
doThrow(networkError).when(mockSearchRepository).search(INVALID_QUERY)
presenter.search(INVALID_QUERY)
verify(view).hideLoading()
verify(view).setErrorMessage(networkError.message)
}
@Test
fun givenErrorCode1003_whenSearch_shouldHandleError() {
···
viewModel.search(INVALID_QUERY)
assertEquals(viewModel.loading.value, false)
assertEquals(viewModel.errorMessage.value, networkError.message)
}
Presenter
ViewModel
ViewModel Testing
! Assert data values

! Verify Observer onChanged() events

! Dependency for testing LiveData

! testImplementation “android.arch.core:core-testing:{version}“

! @Rule 

val instantTaskExecutorRule = InstantTaskExecutorRule()
@Test
fun givenErrorCode1003_whenSearch_shouldHandleError() {
···
val mockObserver = mock<Observer<Boolean>>()
viewModel.loading.observeForever(mockObserver)
viewModel.search(INVALID_QUERY)
assertEquals(viewModel.loading.value, false)
verify(mockObserver).onChanged(false)
}
class SearchActivity : AppCompatActivity() {
viewModel.loading.observe(this, Observer {
it?.let {
if (it) loading.visibility = View.VISIBLE
else loading.visibility = View.GONE
}
})
}
SearchActivity
Mockito features
! verify(), reset(), never(), doThrow()

! verifyNoMoreInteractions()

! verifyZeroInteractions()
@Test
fun givenErrorCode1003_whenSearch_shouldHandleError() {
···
val mockObserver = mock<Observer<Boolean>>()
viewModel.loading.observeForever(mockObserver)
viewModel.search(INVALID_QUERY)
verify(mockObserver).onChanged(false)
reset(mockObserver)
// For making sure interaction(s) never happened on mock
verifyNoMoreInteractions(mockObserver)
verify(mockObserver, never()).onChanged(any())
// For finding redundant invocations
verifyZeroInteractions(mockData1, mockData2)
}
Thank you
@imkimkevin / imkimkevin@gmail.com
Kevin Yongjun Kim
References
! https://www.youtube.com/watch?v=5qlIPTDE274
! https://medium.com/google-developers/viewmodels-persistence-
onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090
! https://developer.android.com/topic/libraries/architecture/viewmodel

More Related Content

What's hot

Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!Artjoker
 
Android Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, VonageAndroid Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, VonageDroidConTLV
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019UA Mobile
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New EvolutionAllan Huang
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin componentsPeter Lehto
 
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern ApplicationsCode to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern ApplicationsCaleb Jenkins
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtAlina Vilk
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applicationsGabor Varadi
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiqueDenis Voituron
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Mahmoud Hamed Mahmoud
 
Dialogs in Android MVVM (14.11.2019)
Dialogs in Android MVVM (14.11.2019)Dialogs in Android MVVM (14.11.2019)
Dialogs in Android MVVM (14.11.2019)Vladislav Ermolin
 
Smooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewSmooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewAndrea Prearo
 
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...Marco Tusa
 
important struts interview questions
important struts interview questionsimportant struts interview questions
important struts interview questionssurendray
 
What's new in Java EE 7
What's new in Java EE 7What's new in Java EE 7
What's new in Java EE 7gedoplan
 

What's hot (20)

Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
 
iOS Talks 6: Unit Testing
iOS Talks 6: Unit TestingiOS Talks 6: Unit Testing
iOS Talks 6: Unit Testing
 
Android Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, VonageAndroid Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, Vonage
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin components
 
iBATIS
iBATISiBATIS
iBATIS
 
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern ApplicationsCode to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applications
 
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC BelgiquePrésentation et bonnes pratiques du pattern MVVM - MIC Belgique
Présentation et bonnes pratiques du pattern MVVM - MIC Belgique
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Dialogs in Android MVVM (14.11.2019)
Dialogs in Android MVVM (14.11.2019)Dialogs in Android MVVM (14.11.2019)
Dialogs in Android MVVM (14.11.2019)
 
Smooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewSmooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionView
 
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice V...
 
important struts interview questions
important struts interview questionsimportant struts interview questions
important struts interview questions
 
What's new in Java EE 7
What's new in Java EE 7What's new in Java EE 7
What's new in Java EE 7
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 

Similar to Android Jetpack: ViewModel and Testing

Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT TalkConstantine Mars
 
Architecture Components
Architecture Components Architecture Components
Architecture Components DataArt
 
Android architecture components - how they fit in good old architectural patt...
Android architecture components - how they fit in good old architectural patt...Android architecture components - how they fit in good old architectural patt...
Android architecture components - how they fit in good old architectural patt...DroidConTLV
 
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)[2019] 벅스 5.0 (feat. Kotlin, Jetpack)
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)NHN FORWARD
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture ComponentsBurhanuddinRashid
 
MVC pattern for widgets
MVC pattern for widgetsMVC pattern for widgets
MVC pattern for widgetsBehnam Taraghi
 
Optimize CollectionView Scrolling
Optimize CollectionView ScrollingOptimize CollectionView Scrolling
Optimize CollectionView ScrollingAndrea Prearo
 
Controllers & actions
Controllers & actionsControllers & actions
Controllers & actionsEyal Vardi
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
Say bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinMiquel Beltran Febrer
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Survive the lifecycle
Survive the lifecycleSurvive the lifecycle
Survive the lifecycleSimon Joecks
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBTAnton Yalyshev
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.UA Mobile
 

Similar to Android Jetpack: ViewModel and Testing (20)

Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
 
Android architecture components - how they fit in good old architectural patt...
Android architecture components - how they fit in good old architectural patt...Android architecture components - how they fit in good old architectural patt...
Android architecture components - how they fit in good old architectural patt...
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)[2019] 벅스 5.0 (feat. Kotlin, Jetpack)
[2019] 벅스 5.0 (feat. Kotlin, Jetpack)
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture Components
 
MVC pattern for widgets
MVC pattern for widgetsMVC pattern for widgets
MVC pattern for widgets
 
Optimize CollectionView Scrolling
Optimize CollectionView ScrollingOptimize CollectionView Scrolling
Optimize CollectionView Scrolling
 
Controllers & actions
Controllers & actionsControllers & actions
Controllers & actions
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
Say bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & Kotlin
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Survive the lifecycle
Survive the lifecycleSurvive the lifecycle
Survive the lifecycle
 
MVVM Lights
MVVM LightsMVVM Lights
MVVM Lights
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBT
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
Model viewviewmodel2
Model viewviewmodel2Model viewviewmodel2
Model viewviewmodel2
 
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.
MVVM with Databinding and Google's new ViewModel. UA Mobile 2017.
 

More from Yongjun Kim

Android DataBinding (ViewModel, UI Modularization and Testing)
Android DataBinding (ViewModel, UI Modularization and Testing)Android DataBinding (ViewModel, UI Modularization and Testing)
Android DataBinding (ViewModel, UI Modularization and Testing)Yongjun Kim
 
Google I/O 2018: All of the News from Keynote
Google I/O 2018: All of the News from KeynoteGoogle I/O 2018: All of the News from Keynote
Google I/O 2018: All of the News from KeynoteYongjun Kim
 
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징Yongjun Kim
 
How to use vim in Android Studio, Useful customization IdeaVim
How to use vim in Android Studio, Useful customization IdeaVimHow to use vim in Android Studio, Useful customization IdeaVim
How to use vim in Android Studio, Useful customization IdeaVimYongjun Kim
 
플리토 코드리뷰 - Code Review in Flitto
플리토 코드리뷰 - Code Review in Flitto플리토 코드리뷰 - Code Review in Flitto
플리토 코드리뷰 - Code Review in FlittoYongjun Kim
 

More from Yongjun Kim (6)

Android DataBinding (ViewModel, UI Modularization and Testing)
Android DataBinding (ViewModel, UI Modularization and Testing)Android DataBinding (ViewModel, UI Modularization and Testing)
Android DataBinding (ViewModel, UI Modularization and Testing)
 
Google I/O 2018: All of the News from Keynote
Google I/O 2018: All of the News from KeynoteGoogle I/O 2018: All of the News from Keynote
Google I/O 2018: All of the News from Keynote
 
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징
Android Studio에서 vim사용과 오픈소스 ideavim 커스터마이징
 
How to use vim in Android Studio, Useful customization IdeaVim
How to use vim in Android Studio, Useful customization IdeaVimHow to use vim in Android Studio, Useful customization IdeaVim
How to use vim in Android Studio, Useful customization IdeaVim
 
Where is CEO?
Where is CEO?Where is CEO?
Where is CEO?
 
플리토 코드리뷰 - Code Review in Flitto
플리토 코드리뷰 - Code Review in Flitto플리토 코드리뷰 - Code Review in Flitto
플리토 코드리뷰 - Code Review in Flitto
 

Recently uploaded

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 

Recently uploaded (20)

Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 

Android Jetpack: ViewModel and Testing