Transferring large amounts of data to Activity using putExtra(); - android

The application passes large number of objects (about 150 objects after parsing JSON format) via intent.putExtra();
Among them are serialized objects.
And the process of opening a new activity takes about 2 seconds...
Is there a way to speed up this process?

If you just want to pass data from one activity to another you can just use a static variable that is accessible from both activities. This eliminates the need to serialize and deserialize all the objects. Example:
public class Globals {
public static List<MyObject> myObjects;
}
In one activity you can set the data you want to pass in Globals.myObjects and the receiving activity can get it from there.
Be aware that this mechanism does have some drawbacks (like when Android kills your process and restarts it later). However, this can be the least troublesome way to simply hand a lot of objects from one activity to another.

One suggestion could be:
Use parceable where you are using serializable
Another suggestion could be:
Use something else to save/restore the data. e.g. a database

I think using a Singleton class for sharing large amount of temporary data between activities is a great way to go. Keeps it really quick and simple.
Although it can be done through Android Parcelable but it has storage limitation which can cause this error "!!! FAILED BINDER TRANSACTION !!!"

Related

Parcelable out of memory

Suppose we have a list of complex objects (primitives and other objects inside) requested from a server to show them inside a RecycleView. In adapter we need only some data from each object, let's say 70%.
I get from server list with full data objects, and each object implements Parcelable so when I select a item I pass object via intent to MyDetailsActivity like so:
Intent intent = new Intent(context, MyDetailsActivity.class);
intent.putExtra("foo", myComplexObject);
startActivity(intent);
This is working as expected but on some low memory devices I get out of memory errors. So my question is how to achieve this type of data flow?
One possible solution is to implement get/set for MyObj in Applicattion class, and pass it like so but I'n not sure if it's stable.
And of course I can pass just an id from MyObject and do another request call inside DetailsActivity's onCreate(), but this requires user to wait some more seconds to load data.
Any advices or references are apreciated
As you have experienced, sending data through the bundle/intent extras has its memory limits.
Your options are to either keep those objects in memory and access them via some static/singleton instance or to do the data query from your server in the desired activity that will show them in your list.
Another viable options is to store the data in a database for ex and read it once its required but this ofcourse depends on your current architecture... you can checkout Realm, Room, GreenDao database options etc...
Second approach is more suitable for mobile applications since you only load data in list via API which is visible inside the recycler view, you can pass that data to activity and then in activity load the remaining data from another call for that specific item.
I'm assuming that each object of the data coming from the server is not of same size, leading to out of memory on some but not all the objects. So the better approach is to also modify server apt (if possible) to send only info which is required for the list in your call's response and have separate resource url to access full information for that object.
This may result in a minimal delay but it will not cause unexpected out of memory errors which is a big let down for the end user.
You can actually use Application class for this purpose, to make it even better
Set the data in Application class when you intend to pass
Retrieve the data at destination into Local variable from Application
After retrieving data into local variable, set object in Application to null
Using above approach will make sure your objects memory is released as soon you consumed it without holding it all the time throughout Application Lifecycle

Android, performance of transferring data between activities

Which one of two ways below has better performance for transferring data between activities?
Activity1: putExtra("id" , customerId)
Activity2: Select on the table and fill Customer object
Activity1: putExtra("customer", customer)
Activity2: Customer customer = (Customer)getIntent().getExtras().getSerialaizable("customer");
I mean send a unique item (like id) to the next activity and then select it from data base OR send the whole object to the next activity and cast it?
Obviously first way. You just send the ID of the object and then read it from the database in second Activity. The other way involves serialization/deserialization which costs CPU-cycles. Even using Parcelable will still use significant CPU-cycles.
On the other hand, I doubt that you would notice any performance penalties unless you are doing this for a bazillion objects. Do whatever is more straightforward and easier to understand/maintain.
Serializable is not recommended in android, check parcelable it's faster.
Serialization vs DB depends on object complicity, only profiling can show the picture, but for a one object it's neglectable.
The fastest way would be to store object in memory and share through singleton.

Is passing with serializable or parceable an efficient solution?

Im building an android app and in the startup activity i parse a pretty big json file (3.3 mb) into custom objects, or when there was no update i retrieve it from a serialized bytearray. Im dealing with one object with a list of about 500 objects with subobjects, lists etc.
Now i need this data, or some of it in my other activities. What is the best solution for this?
It seemed a lot of data processing to serialize and deserialize using intent.putExtra or using parceable everytime you start a new activity. Is this processing less than i think or is there a way to use your parsing class and don't destroy it so you can use something like
Myclass.get(nrIneed).Mysubclass.getsomestring
?
This is how i did it when using data for logging or something in my parsing activity.
You can use Application class to store this data and you can use it across all the Activity
public class BusinessClass extends Application
{
public ParsedData parsedData = new ParsedData();
}
Then call it in any activity using following code
BusinessClass appState = ((BusinessClass)getApplicationContext());
appState.parsedData.getData();
For more info
http://developer.android.com/reference/android/app/Application.html
You SHOULD NOT use Parcelable for objects which may consume memory more than about 1MB. Otherwise the parsing will fail (at least as per API level 8).
However, in your case, I would recommend you to save/organize the parsed data into SQLite and query it from other activities. This will help your app to eat less memory :)
You may also create a static reference to your object, but since its huge in size, I wouldn't recommend you, because then your app will become an appealing target for android VM to kill - when running under low memory circumstances.
I think you shouldn't use your data as a big Json file. At the first launch you should save your data in a database then only use this db when you need to Create/Retrieve/Update/Delete.
If you really want to use your JSON file, then you should make it static (in your application singleton for example).
Hope this will help you

Passing/Using non primitive objects between Activities

I need to pass a List of my objects between activities. I do not want to use parcelable or serialize the data each time. I also do not want to save it in a local file or database. That probably leaves me with using static objects.
Lets say I to use ListA between activities Activity1 to Activity2. I ca
Approach1: Create a static ListA in one of those activities and do all my stuff of that static ListA.
Approach2: Create a static list in another class which I use just for storing this List and doing all my stuff on this list. But this means that this stays as long as my process is running and I have to manually set it to null when I do not need it.
Approach3. I am extending the above class to implement it using a static HashMap.
I have two methods one to store the list in a static HashMap using a unique key and another method to retrieve the list and remove it each time data is retrieved so that the List is no longer present in the static HashMap. So we essentially have to pass only the random key generated to store data between activities which I can pass as an extra using Intents.
Will there be any issues when I use any of the above approaches and which will be the best approach.
I'd consider creating an Application object and using it like a singleton to access your data. I've described the approach here: http://chrisrisner.com/31-Days-of-Android--Day-7%E2%80%93Sharing-Data-Between-Activities. Some people don't seem to like using the Application object in this manner but it makes more sense to me than putting a static object on an Activity.
Uggg statics! Man I wish all developers understood global variables are bad and how they make your program more brittle and your life hell. We only been talking about how bad they are for 30+ years, but unfortunately no one figures this out until they've utterly hung themselves on them.
First I'll say serializing your data is fast. There are great tools out there that will serialize your objects quickly that you can use I prefer http://flexjson.sourceforge.net for this.
So if you are just outright opposed to this you can pass this object through the Application by subclassing it, declaring your implementation in your Android Manifest, and each activity has access to the Application instance:
public class MyActivity extends Activity {
public void onCreate( Bundle bundle ) {
MyApplication application = (MyApplication)getApplication();
Object anInstanceFromAnotherActivity = application.getSomeInput();
}
}
The downside to this is when your application is reclaimed if the user returns to your application the memory is gone, and you can't get that input you might need of your screen. Android framework is trying to make you serializing things in the bundles because if it decides to destroy your application you can always rebuild yourself from the bundle. Now there are short cuts you can take like redirecting people to start over if the Application has been reclaimed, but those depend upon your program and what its doing if they make sense.
That's where using serialization wins out over all other forms of persistence (parcelables, files, databases) because it can be done in one line of code.

Passing data of a non-primitive type between activities in android

Suppose you want to start a new activity and pass it some data from the current activity. If the data is of a primitive type you could simply use an intent and add extras, but how would you do this for more complex data structures like arraylists or objects?
You have a few options:
You could wrap the more complex structure in a class that implements the Parcelable interface, which can be stored in an extra
You could wrap the more complex structure in a class that implements the Serializable interface, which can be stored in an extra
You use static data members to pass stuff around, since they are all in the same process
You use external storage (file, database, SharedPreferences)
As the person who just posted noted, use a common component, such as a custom Application or a local Service
What you do not want to do is pass big stuff via extras. For example, if you are creating an application that grabs pictures off the camera, you do not want to pass those in extras -- use a static data member (icky as that sounds). Intents are designed to work cross-process, which means there is some amount of data copying that goes on, which you want to avoid when it is not necessary for big stuff.
One option I am aware of is storing the data you are using in an Application object which all your activities can retrieve from context.
I have also heard of using Google Protocol Buffer to achieve a higher performing solution

Categories

Resources