Can I use ViewModel to send data to the server? - android

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

Related

RxJava2 repository cache with observers concurrency

I have a repository making a network call via a datasource.
I have two use cases that both call that reposository to get the resource but are making different treatments.
Those use cases are subscribing at the same time.
The behavior I want is to make the network call on first subscription, block the other ones and then cache the data to observers in queue.
For now I have a fetch method in the repository actually making the network call (called at one place in my code). I have a get method that return a behavior subject that is valued when the fetch method get data (the uses cases are observing this behavior subject).
I don't like having those two methods and I think it should be transparent. In an ideal case the use cases should call a single repository method and get data (the first one making the network call because cache is missing, the second one getting the cached data).
Is there a way to do this with RxJava ?

Pattern for notifying Activity of a network status code

I have many Activities that have several fragments. Part of the work those fragments do is to make authenticated network calls. It is possible that the token will expire. When that happens, I will see the 401 in the networking layer. What is the preferred method to communicate back to up the stack to whichever fragment initiated the network activity that it needs to initiate the logoff procedure? In other words, when the networking layer gets a 401, I want to communicate that back to the UI that the user needs to be log offeven though many other Activities may have also been invoked since then. This is often done via custom exceptions being handled in the app but I was wondering if there was a specific pattern that was preferred other than that. Something using Live Data perhaps?
You should separate in layers. Each layer should be responsible of a single task. There are many ways to do this, but you could use the MVVM Google approach which consists in:
M (Model): data classes and repositories that persist/retrieve them.
V (View): Activities/Fragments that observe data objects (LiveData) exposed by the VM and also call actions of the VM.
VM (ViewModel): Exposes actions, e.g. login, internally calls a Repository which calls the API (e.g. using Retrofit2), when it receives a result, it updates the data objects observed by the V.
Have a look at:
ViewModel
LiveData
Codelab

A Technique to share data received from network call between multiple activities

Currently I'am developing app which having a bad API. I have a situation where I have to use data received from network call in a activity, which is 2 steps away from the activity where I made the network call. In other word all the data necessary fill 3 activities comes on this one network call.
So I pass necessary data between activities using Intent Extra. It is not easy to maintain and It takes noticeable time to switch between activities.
I know one possible solution is to store data in database. and access those data from different activities. It feels like a bad practice because no use of those data after user pass 3rd screen.
Is there any better technique to handle this?
You can put all your network logic in the separate class, cache data in some variable and use it in your activities (you can use singleton class or injecting by dagger).
Also you can read about Clean Architecture and get some good practices from it.
If you don't want use anything from above, you can remove data from database after using and not store it forever. Or you can use SharedPreferences if your data is not complex.

How to handle rotation with Retrofit and RxJava/RxAndroid in Activity?

I read here that we can use some global cache in order to handle rotation.
You can prevent this by using the cache or replay Observable operators, while making sure the Observable somehow survives the Activity life-cycle (for instance, by storing it in a global cache, in a Fragment, etc.)
But how to achieve that? Somebody can point me to some example how to do it?
Or maybe you know some better approach to handle configuration change?
EDIT:
For now I have found many ways, but I ended up with using RxBus realisation. Nice example of using RxBus you can find here.
I have made a demo application (https://github.com/pmellaaho/RxApp) in order to experiment how tackle the kinds of situations in Android application. To put it short 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.
I've recently used Loader combined with ConnectableObservable to handle better rotations during RxJava2 stream. I've even created a Medium Post explaining in details my approach.
Basically, you have to put the observable (ConnectableObservable) in a Loader with a Transformer, and next re-subscribe to it when activity/fragment resume after being destroyed.

creating a call back for AsyncTask in a model to update an activity

I'm creating an app in an MVC pattern... and I'm trying to do most of the data getting and manipulation on the Model side of things so I don't clutter up the Activities with code that does not belong there, but the one thing that's tripping me up a bit is AsyncTask... from what I've seen it seems that this is called most of the time in the UI because it allows you to update. the problem with that is I am doing all my network calls using AsyncTask from my model not my activity. But I still want to update my UI when cretin things happen such as a network call returned something put it in the ui.. so is there a way to make a call back from a model to the Activity or something to that effect, so I don't have to put that code in the activity?
any help would be greatly appreciated.
What you need is an interface which acts as an update "listener" in your Model. That way, your activity can register with the listener when it is active and receive notifications of changes accordingly.
There are many examples (and built-in listener classes) - here is one:
http://www.tutorialspoint.com/java/java_interfaces.htm
Creating an interface in your Activity that is registered in your model allows your model to notify the interface of changed data in order to update properly. If you implement your model as a service or maintain instances of them in a service, then you can bind to the service and then register your listener assuming your model processing extends beyond the life of activities.
If not, AsyncTask is where model processing should occur and you can implement your model synchronously and use listeners to monitor it.

Categories

Resources