0

I was looking for a way to pass array of objects to my activity/fragment. The first thing that came up to my mind was making the object Parcelable and then pass it inside an intent as a list. However, Parcelable concept is mainly designed to be used across process boundaries like when, for example, you want to start a new activity, or send a broadcast. This is why it's also recommended to keep the size of things smaller in the intent (preferably a few KB) since each process has it's own private binder transaction buffer to be used at the OS level.

My first question is do you think I might be missing some points in the above arguments?

Secondly, when I use LocalBroadcastManager to send my broadcast, does the data inside the intent still goes down to the OS level to get marshalled/unmarshalled and passed back to the process? If it doesn't, perhaps it make more sense to pass relatively huge arrays since it wouldn't be occupying any shared space in the OS memory on behalf of my process (assuming the data won't leave my app when use LocalBraodcastManager).

Hope it's clear!

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
stdout
  • 2,471
  • 2
  • 31
  • 40
  • What is this huge array are you referring to? Can you not consider storing it to the database instead and fetch it to upcoming activity instead since you only need to pass a lightweight key. – Enzokie Dec 31 '17 at 15:07
  • Sure you can but the data resource/provider is not my point. Let's say you have a method getItems(). One option is you can pass a listener and call the relevant callback when data is ready. The other one is - if you don't want to really want to depend on any sort of listener interfaces, or want to be really very async - to listen an (broadcast) event in which the data is returned with an intent. – stdout Dec 31 '17 at 15:20

2 Answers2

1

If you have a lot of objects, it makes little sense to serialize and deserialize (parcel and unparcel) them when sending them from one component of your app to another. Assuming all components of your app live in the same OS process (which is the default behaviour), you can share these objects by putting them in static member variables. See https://stackoverflow.com/a/10909959/769265 for an example.

There are downsides to this approach. If Android kills your process, when the user returns to the app, the static member variable may not have been set up. You'll need to deal with this situation and act accordingly.

Other methods of dealing with large objects (or large arrays of objects) are:

  • Store in SharedPreferences (you will need to serialize the object into a byte stream to save it in SharedPreferences)
  • Store in SQLite database (you can use a custom schema and store the data as efficiently or inefficiently as you want)
  • Store in a file (you can either serialize the data to a byte stream and write to a file, or you can use the methods that Java offers to write "objects" to a file)
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • Thanks for the input David. Using 'static' is seems like one option. Apart from that, what I'm more curious about is how to pass this list of objects to an upper layer (in our case ui) instead of how to provide it (might be through shared prefs, a database, a file or sth else). – stdout Dec 31 '17 at 17:08
  • I do not understand what you mean by "pass". If your UI (`Activity`) and other component (`BroadcastReceiver` or `Service`) is running in the same OS process (which is the default), you don't need to "pass it". You just put it in a `static` variable and the other class can just reference it from there. – David Wasser Jan 01 '18 at 13:35
  • Actually, you got me correctly. By 'passing', I just meant forwarding the relevant result/data from core to ui using (preferably) an android way and in a decoupled manner. As you suggested, using static is one way to go, but doesn't seem like the best design? If you look at the second part of my question, that's why asked if we can still take advantage of intents by utilizing LocalBroadcastManager. – stdout Jan 01 '18 at 22:56
  • 1
    I assume (because I haven't looked at the code or tried it out myself) that even using `LocalBroadcastManager` the objects will still be serialized and deserialized (marshalled/unmarshalled). The only thing that the `LocalBroadcastManager` does differently than sending a regular broadcast `Intent` is that it doesn't need to use IPC to (potentially) send the broadcast to other processes. – David Wasser Jan 02 '18 at 12:27
  • That's even more interesting. If it doesn't need IPC,then why do I still need to marshall/unmarshall things since I don't go out of my process. Aside from that, that might also mean I can pass (relatively) large set of objects since I don't go down to os level. – stdout Jan 06 '18 at 13:48
  • The marshalling/unmarshalling happens as part of sending an `Intent. When you send an `Intent`, Android serializes (parcels) the `Intent` and saves it in internal Android (system) data storage for later use. If Android needs to kill your process and later create a new one, it uses the saved `Intent` to recreate the original situation. I think it is a mistake to put a large number of objects in an `Intent` as extras. The schem was not designed for that. If you need to pass a large number of objects between components in your app then you have the wrong architecture. – David Wasser Jan 07 '18 at 20:31
0

use bundle object, it use a string key-object configuration, and it's very easy to use

  • It might be easy to use but it can't carry huge data. – Enzokie Dec 31 '17 at 15:15
  • what type of data you have to pass? –  Dec 31 '17 at 15:18
  • Say it's an array of custom objects each having 100 fields. But the point is how would you pass this bundle to your activity? – stdout Dec 31 '17 at 15:30
  • i've don't understand a lot your question... if you want the code is in the first activity Intent intent = new Intent(this,YourClass.class); intent.putExtra(name, array[]) startActivity(intent); and in the second int[] array = intent.getIntArrayExtra(name); –  Dec 31 '17 at 15:41
  • @AlbertoSinigaglia that's the whole point of my question. Of course you can pass it through an intent but the problem is intents are not designed to be used to pass large list of objects across components. – stdout Jan 01 '18 at 22:52
  • @zgulser i’m not so sure that it could be a possible option, but making it static? I don’t know the lifecycle of a static application in Android, so i’m not sure about this possibility –  Jan 02 '18 at 00:06
  • @zgulser give a look at https://stackoverflow.com/questions/4878159/whats-the-best-way-to-share-data-between-activities ..... i think it could help you –  Jan 02 '18 at 00:12