So, I am using workmanager to retrieve data from an FTP server. I have to display one type or information or another type deppending on the state of the worker.
I was using getWorkInfoByIdLiveData on the viewmodel and I was observing the state of the worker on the activity. But, as the Observer is almost deprecated I am trying to use Flow instead.
The problem that I have is that I don't know why, I can't use the asStateFlow() on the livedata. enter image description here
Does anyone know a way to observe the state of a worker without using LiveData and Observer?
Thank youuu
Related
In 2022, What scenario can imagine LiveData is better than other observable libraries such as StateFlow, SharedFlow, Coroutine Channel and etc.
Based on philip lackner :
If you need to store a value that can change over time(state), use state flow or live data , otherwise use shared flow or Channel
If you like Coroutines use State Flow, Live data use main thread. Live data is lifecycle-aware while state flow is not lifecycle-aware by default but can be using lifecycleScope + repeatOnLifeCycle(). Both of them use in ViewModel to store UI state.
If you have multiple observers, use shared flow instead of channel. Both of them use to send one time events(like when the user successfully connected). Shared flow use coroutines.
I am using the Single-Activity and Multiple-Fragments approach, and I have one fragment that has a ViewModel with LiveData. The UI always changes when there is a change in a remote database (Firebase Realtime Database). I followed steps that are described in the offical Firebase Blog (https://firebase.googleblog.com/2017/12/using-android-architecture-components.html). However, the fragment, which the LiveData and ViewModel are bound to, is not active (because I navigated to another fragment) I don't get a notification if something changes in the database.
What I would actually want is to get informed when something changes in the Firebase database no matter which fragment is active, because I would like to play a small notification sound such that the user knows that something has changed. When the fragment that is bound to the LiveData is not active, the UI should not be updated, but the notification sound should be played.
My question is whether this is possible with LiveData (Mutable LiveData) in combindation with Firebase Realtime-Database and if so, how can I do this? I think by default, LiveData only notifies and executes code, if the fragment is active.
Reminder: Any idea how to do that? I'll appreciate every comment.
There are a few ways of doing that depending on the desired behavior. If you want to be notified whenever data changes and your application is active you can do the following:
Ensure that you have a data or repository class that is scoped to the lifecycle of the application. Since you are using single activity architecture, you can also use an activity scoped view model.
Firebase already provides you a way of being notified whenever data changes through onDataChange() listener. You should listen to these changes in you data/repo/viewmodel class and react to changes whenever your data changes.
If you have the scoping done correctly, you'll be notified regardless of which fragment you are on. You can then react to those changes (play sound) as needed.
Currently, I am using ViewModel to load a list of Shows in my app. Then, I display it in the main screen. It survives to configuration changes and does not provoke memory leaks since ViewModel has this features.
Now I need to do something a bit different. I need to log in a user making a network call to an endpoint using retrofit 2 and rxjava 2, he will type the email and password, and then will be redirected to the MainActivity. Second, I also need to update the user information, he types his new information and then I send to the server.
May I use ViewModel to log in a user or to update user information? If not, what sould I use instead?
What I need
This retrofit 2 call should survive to configuration changes, as rotating the screen, and it can not cause memory leak.
What I tried
Calling retrofit using enqueue() method in the MainActivity. Obs: This approach is not good because it puts to much things in the ui class, it provokes memory leaks.
Using static inner classes. Obs: It does not survive to configuration changes, as I need to cancel the task in onDestroy().
MVP seems fine to login a user.
You can check google sample project, specifically this class
https://github.com/googlesamples/android-architecture/blob/todo-mvvm-databinding/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskViewModel.java
Usually you would trigger the network operation in the model view, while the code for implementing the network logic is written in a different class (ApiManager for example), and then get the results in your ViewModel
LoginViewModel will have an object of some network manager class
When you click login, the viewmodel will call networkManager.performLogin()
Results are then passed to the viewmodel (RxJava is handy in here).
In your ViewModel do whatever processing you need when you receive the results
I want to request a sync of my sync adapter every time a change happens to some of my data. Having LiveData I wonder if the correct way would be to bind a observer to the data within the application lifecycle.
Does anyone know what the "official" way of doing this is?
I work with RxJava and RxAndroid. How resume the work of an observable if a configuration change occurs (activity rotation, language locale change etc.)?
I need not only resume the work of an observable, also I need save emitted items, when subscriber is unsubscribed and emit all saved items right away after subscription.
I read a ton of articles, but I didn't find the answer to my question.
I found a few examples, but none of them does not solve the problem:
https://github.com/alapshin/rxweather
https://github.com/kaushikgopal/RxJava-Android-Samples
https://github.com/tehmou/rx-android-architecture
https://github.com/richardradics/RxAndroidBootstrap
You can use one of the ConnectableObservables. Particularly, cache or replay would be handy for this kind of situation.
For example, you can call cache on your observable, unsubscribe it when activity is destroyed, and resubscribe it again after the activity is recreated.
I have made a demo application (https://github.com/pmellaaho/RxApp) in order to experiment how to tackle these kinds of situations. Basically, I use a singleton model from Activity to get the response from network. This makes it possible to cache responses, access the data from multiple UI components, subscribe to pending request and also to provide mock data for automated UI tests.
You can use OperatorFreeze from this library for pausing Observable when activity is recreating. You need pass instance of this operator to method Observable.lift(). You don't need to unsubscribe from Observables when you use persistent Presenter.