I'm trying to pass array list of custom object between 2 activities throw intent but i got this error and i don't know how to solve it. i 'll appreciate if anyone can help me! Thanks in advance.
Method in pass in 1'st activity:
i.putParcelableArrayListExtra("key", (ArrayList<? extends Parcelable>) result);
startActivity(i);
Method in get in 2'st activity:
Intent i = getIntent();
ArrayList<ItemObjects> list = i.getParcelableArrayListExtra("key");
Error Log:
12-25 09:11:49.546 17742-17742/com.example.baha.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.baha.myapplication, PID: 17742
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1514)
at android.app.Activity.startActivityForResult(Activity.java:3917)
at android.app.Activity.startActivityForResult(Activity.java:3877)
at android.app.Activity.startActivity(Activity.java:4200)
at android.app.Activity.startActivity(Activity.java:4168)
at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:127)
at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:62)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.os.TransactionTooLargeException: data parcel size 12404332 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:503)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2657)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
at android.app.Activity.startActivityForResult(Activity.java:3917)
at android.app.Activity.startActivityForResult(Activity.java:3877)
at android.app.Activity.startActivity(Activity.java:4200)
at android.app.Activity.startActivity(Activity.java:4168)
at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:127)
at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:62)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
All answers provided seem a little low quality. So I will provide another one.
The problem
The exception you're getting is caused by the fact that the amount of data you're trying to transfer through an Bundle is simply too large.
Note: I wrote a blog post about this topic on my website, it contains more detailed information. You can find it here: http://neotechsoftware.com/blog/android-intent-size-limit
Solutions
There is no way you will be able to transfer you're object through the standard way (using a Bundle or Parcel), because it is simply too large. There are two solutions that are often used in these cases:
File based
You could store the array of custom objects in a file and later read it back. I don't recommend doing this as its in general slower than in-memory storage. However an often used technique is to use a database of some sort if applicable. Using a database however has a major drawback, objects stored in the database are often temporary objects so you need to remove them after you're finished reading them. If something goes wrong your database may start to contain clutter. So you need some sort of clean routine. The best method to avoid this is probably to write the database file (or actually any file used for this) to a cache directory.
In-memory 1: (Application instance)
Your best option (and probably the preferred Android way) is to store the array in the Application
instance. To do this you would need to create a class and make it extend Application
. In this class you create a public field to write and read the array to.
public class App extends Application {
public ArrayList<YourObject> objects;
}
You can read and write to this field by obtaining the Application
instance.
App app = (App) getApplicationContext();
app.objects = yourArrayList;
Don't forget to register your extended Application
class in the manifest.xml
file! Why does this work: This works because the Application
instance won't be destroyed between the different Activities, it has a life-cycle independent from the UI.
In-memory 2 (singleton)
Another option is to use the singleton pattern or create a class with static fields. The example below demonstrates the singleton pattern.
public class DataContainer {
private static DataContainer instance = null;
public static DataContainer getInstance(){
/**
* Synchronizing this method is not needed if you only use it in
* Activity life-cycle methods, like onCreate(). But if you use
* the singleton outside the UI-thread you must synchronize this
* method (preferably using the Double-checked locking pattern).
*/
return instance != null?instance: (instance = new DataContainer());
}
public ArrayList<YourObject> objects;
}
DataContainer.getInstance().objects = yourArray;
Very important note on in-memory object storage: Assume that your app is in the background and you stored some object in the
Application
instance (or in a singleton container) to later restore it. If the Android system decides to kill your app because it needs to free some memory for another app, your objects will be destroyed. Now the important part, if the user returns to your app the Android system re-creates the destroyedActivity
and passes a non-null "saved-instance-state"Bundle
to theonCreate()
method. You might assume at this point (because theBundle
is non-null) your in-memory stored objects exist, this is however not true! Conclusion: Always check if stored objects are non-null!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With