Passing data from IntentService - java

I have the following flow:
ActivityA/FragmentA passes to ActivityB/FragmentB via intents a custom somewhat large object.
Among the attributes of the object is a List<CustomObject> items
User presses a widget in FragmentB and then FragmentB starts ActivityC/FragmentC passing also that custom object (Parcelable) that is supposed to show details in its UI and also starts a Service to fetch the list that populates the items of that specific object.
When Service fetches the result from a background HTTP call I need to update the list in the UI that is expected to display these items fetched.
This list is in FragmentC which has a copy of the custom object with the items null.
The Service has another copy of the custom object and the items just fetched but can not update the list of the fragment.
Making a static variable of the fragment and assigning this and then exposing a public method in the fragment that the Service can call to pass the items works but is very dirty.
I was wondering what is a clean/standard design for this?

I am using LocalBroadcastManager but the list is fairly large and I am not sure if passing it via the intent is a good idea
Normally, when we use an Intent, it is to cross process boundaries, and so the Intent has to be converted into a byte array (by means of a Parcel), and that gets to be a problem with large data. LocalBroadcastManager does not do that -- it just passes the Intent object around as is.
The downside of LocalBroadcastManager is that the message is an Intent, and because an Intent is usually used for IPC, it has limitations on data types. Personally, I recommend greenrobot's EventBus, or even Square's Otto, over LocalBroadcastManager, for just this reason. That being said, if it is easy enough for you to get your data into an Intent, size should not be an issue.

Related

ViewModel Data Lost When BackPress

firstly I want to say I am sorry. I am newbie in MVVM. I want to know how to retain the data in viewmodel ??
For example I have followed this codelab tutorial https://codelabs.developers.google.com/codelabs/android-lifecycles/#0.
I try to kill the apps then go back into the apps but the data is not saved .Why?
I tried to make new activity by intent it. I ln new activity I implement the same code as statelifecyle. But why when I backpressed and try to enter back the newactivity the data is not saved ?
To answer your questions:
Data in ViewModel is only persisted throughout the lifecycle of your activity. So if your app dies, your data is not saved. If you want it to persist, consider integrating an off-line data persistence library like Room or you can also use SharedPreferences depending on your use case.
According to this post: Android LiveData - how to reuse the same ViewModel on different activities?
When you call ViewModelProviders.of(this), you actually create/retain
a ViewModelStore which is bound to this, so different Activities have
different ViewModelStore and each ViewModelStore creates a different
instance of a ViewModel using a given factory, so you can not have the
same instance of a ViewModel in different ViewModelStores
In other words, different activities cannot share a single ViewModel. So if you want to switch pages while retaining data in your ViewModel, consider using fragments inside your activity instead.

Android: storing JSON data in singleton to pass between activities?

So let's say I have this list activity and when you click an item on the list it takes you to a new activity with more details on that list item. All this info is fetched using REST services. Before I'd use Retrofit to store that data into an object and store that into and singleton class that is accessible by both activities so that when one list item is selected it just takes the id and goes to the singleton to get the right data then use that in the new activity. Is this proper Android practice? Also I was wondering if it's better to have the list activity go to a new activity to present more detail info or use a fragment.
It's your choice to take the details screen as Activity or Fragment.
Fragments are better.
And you can pass the list by making the pojo class as Parcelable between activities or fragments.
Yes, usually we can use Static variables or singleton classes to transfer parameters between activities. You can also use intents to pass variables from one activity to another.

Storing shared values in SQLite database vs passing through intents

My app initially makes a request for a list of objects from a server. These objects are currently kept in memory as an ArrayList<MyObject>. However, I want these objects to be passed through multiple activities before the user terminates the flow by pressing a button. I could make the ArrayList serializable and pass it through Intent extras. But I could also store MyObject(s) in a SQLite database and access/modify them in any Activity without having to go though intents. I was wondering what the norm is to accomplish this.
EDIT: forgot to mention that all the values would be deleted once the user terminates the flow.
SQLite is not the best way to go in your case since you don't need the data to be persistent after you close the app. It will just slow your app having to store and retrieve all entries on every activity transition. You can do one of the following instead:
Pass Serializable the way you described. Might be slower than the other alternatives though
Make MyObject implement Parcelable and use [intent.putParcelableArrayListExtra()](https://developer.android.com/reference/android/content/Intent.html#putParcelableArrayListExtra(java.lang.String, java.util.ArrayList))
Extend Application and load the list from the network in your Application.onCreate() and call getList() from activities that need it. That way you load it once and you don't need to pass it between different activities.

How to pass an object to another activity and reference it in other methods

I am trying to pass an object from one activity to another. But from the methods I've seen, it seems like you always grab that object in the onCreate method, which makes sense. But since onCreate is protected, I'm unable to reference that object in other methods in that activity.
Is there a better way to do this? I'm still getting the hang of all this Android stuff.
use intent for this that is the best way for doing this:-
intent=new Intent(this,yourotheractivty.class);
intent.putExtra("object",object);
startActivity(intent);
get this in your activity's oncreate using the get intent if you are creating a custom object you better use parceable
Using an Intent is one common method of sending an Object around, but it sounds to me like you are looking for something like a generalized observer pattern.
I would create class that holds references to subscriber objects and what callbacks they would like receive. Upon sending a callback and associated data to that class, have the subscriber objects registered to that callback receive the associated data.
Existing solutions:
If you're using Guava it has one built in (https://code.google.com/p/guava-libraries/wiki/EventBusExplained), otherwise take a look at Otto (http://square.github.io/otto/) or EventBus (https://github.com/greenrobot/EventBus).

Notifying view/activity when the data/model changes

I have an Activity A, Activity B and an Object C. I need to start Activity B from Activity A and while starting i need object C to find user location and once it is available Activity B must be notified with the location object.
I am not sure how Object C can notify Activity B since android dosent allow to get hold of Activity References.
Look into implementing a Bound Service. Your location info could be fetched within this service (on another thread, of course), and retrieved within Activity B when it binds to the service.
Create an AsyncTask that will find the user location in the background.
Once completed, you can update the UI or maybe create a notification to the user.
Use Java Observer and Observable classes.
By extending the Observable class on your data object (model), you are able to assign Observers which listen for changes in said data model. When the data changes, the Observer is notified automatically and fires its update() method.
The update() method is an obvious place to put your code which refreshes the views impacted by the changes in data, this is where the linkage between the views and the data model occurs (usually in the Android Activity). The beauty of using the Observer and Observable classes is that the data model, views and controller (the Activity that updates the views) are all separated. That is, you can use the data model for whatever you want, if you change the views it won’t break the data model and vice versa. This makes your app much simpler to understand and easier to update later down the road.
Here's simple code example: http://www.ootpapps.com/eclipse_projects/ObserverExample.zip

Categories

Resources