Architecture Components Flashcards
What is the dependency for implementing viewmodels?
In build.gradle(Module)
implementation ‘androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0’
Where is the best place to perform tasks when an app launches?
The init block of the ViewModel
What are the benefits of using a ViewModelProvider? (3)
ViewModelProvider returns an existing ViewModel if one exists, or it creates a new one if it does not already exist.
ViewModelProvider creates a ViewModel instance in association with the given scope (an activity or a fragment).
The created ViewModel is retained as long as the scope is alive. For example, if the scope is a fragment, the ViewModel is retained until the fragment is detached.
When is the callback ViewModel.onCleared( ) called?
What does it do?
When a Fragment is detached, the ViewModel is destroyed.
onCleared( ) is called just before this happens - to clean up resources.
Demonstrate the steps to implement a ViewModel from a ViewModelFactory that is instantiated in a Fragment and passes in a parameter from navArgs.
1. Create ViewModel class MyViewModel(val myArg: Type): ViewModel( ){ }
2. Create ViewModelFactory: class MyViewModelFactory(private val myArg: Type): ViewModelProvider.Factory{ override fun create(modelClass: Class): T { if (modelClass.isAssignableFrom(MyViewModel::class.java)) { return MyViewModel(myArg) as T } throw IllegalArgumentException("Unknown ViewModel class") } }
- Instantiate both of the above in the fragment:
private lateinit var viewModel: MyViewModel
private lateinit var viewModelFactory: MyViewModelFactory
viewModelFactory = MyViewModelFactory(MyFragmentArgs.fromBundle(requireArguments()).myArg)
viewModel = ViewModelProvider(this, viewModelFactory)
.get(MyViewModel::class.java)
- What two arguments are taken by LiveData.observe( )?
- Where should they be assigned?
- What should be assigned as the first argument?
- LifecycleOwner and Observer(where logic is performed when the value changes)
- LiveData.observe( ) should be called in Fragment.onCreateView( )
- The viewLifecycleOwner should be passed as the Owner
What is the Codelabs way to ensure encapsulation of LiveData values?
private val _myVar = MutableLiveData^Type^( )
val myVar: LiveData^Type^ get( ) = _myVar
In a nutshell, what is the observer pattern?
When using LiveData, what is the Observable and what is the Observer?
An observable is an object that notifies observers about the changes in its state.
LiveData object is the Observable. The Observer is the lambda function in Fragment.onCreateView( )
If using a LiveData to trigger navigation, what must you remember to do immediately after the navigation logic has been defined?
Call a viewModel function that resets the LiveData triggering the navigation back to its original value
Why is Transformations.map( ) used?
How is Transformations.map( ) used?
What else is it important to remember about Transformations.map( ) ? (2)
Why:
It takes one LiveData object, manipulates it, and returns a new LiveData object
How:
val newLiveData = Transformations.map( oldLiveData) {value -^ //manipulate value, potentially to a different Type}
Important to remember:
1. Executed on main thread, so no long-running tasks
- Not executed unless an observer is observing the returned LiveData object
Why extend AndroidViewModel instead of just ViewModel?
AndroidViewModel can provide application context by calling getApplication().
It is, however, problematic for unit testing because context is part of the Android lifecycle.
- What is work Manager for?
- What does WorkManager use for backward compatibility?
- What is the dependency?
- Background work that:
- is deferrable - not required immediately
- requires guaranteed execution - the task will run even if the app exits or the device restarts - WorkManager is compatible back to API 14 (Android 4.0, 2011)
- Uses JobScheduler on API23 (Android 6.0, 2015) and above
- Uses a combination of AlarmManager and BroadcastReceiver on earlier versions. - build.gradle(Module)
implementation “android.arch.work:work-runtime-ktx:$work_version”
What are the three main classes used to implement WorkManager?
Worker - extend this class and override doWork( )
WorkRequest - Uses Constraints (battery, network) to configure how and when doWork( ) can occur
WorkManager - Works with the OS to schedule the work, honouring specified Constraints
Give the syntax for extending the ListenableWorker class and implementing the doWork( ) function
class MyTaskWorker(appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) {
override suspend fun doWork(): Result { try { // work to be done goes here } catch (e: HttpException) { return Result.retry() } return Result.success() } }
NB Result is the result of a ListenableWorker’s computation. It can be success( ), failure( ) or retry( ).
CoroutineWorker extends ListenableWorker.
What is the difference between the Worker class and the ListenableWorker class?
ListenableWorker is the parent class (counterintuitively?)
Worker is recommended, but only for synchronous execution (Worker is destroyed once execution is complete)
Use CoroutineWorker for asynchronous tasks.