0

Android 7.0 start throwing TransactionTooLargeException while restoring instance state if the parcel size is over the limit.

But my application have to save the loaded content which has no size limit. So it's very easy to cause this error.

Is it safe to save instance state in Application instance?

Will it be deleted while the Activity is in background?

Is there a way to save large data without throwing this exception?

Kimi Chiu
  • 2,103
  • 3
  • 22
  • 37
  • Since we don't know the nature of stored data there will be many options. Use a Loader or SharedPreferences or variable in a retained Fragment backed by SharedPreferences/File/etc. – Eugen Pechanec Sep 29 '16 at 12:28
  • I have to save the data which my app downloads from the server. And the data will be parsed into some complicated object. Neither Loader or SharedPreferences can be used in this case. And the fragment will be destroyed after Android kills my app, how could a retained fragment works in this case? What I really want to know is, how to save a large data and restore it when the app is killed by Android? – Kimi Chiu Oct 01 '16 at 10:37
  • When your app is killed, it doesn't exist in memory. So any data has to be loaded from persistent model/storage. Your data set should be persisted on hard drive and loaded to objects as needed. Saved state is not a tool for retaining your whole model. – Eugen Pechanec Oct 01 '16 at 10:41
  • You mean I have to save it into database or cache every time the onSaveInstanceState is called? – Kimi Chiu Oct 01 '16 at 11:16
  • Not at all. Everytime you fetch data from the internet you save it to storage and everytime data in storage changes you broadcast the change to the ui. Your data model does not touch saved state ever. – Eugen Pechanec Oct 01 '16 at 11:25
  • But the save to storage progress draining battery, doesn't it? – Kimi Chiu Oct 01 '16 at 11:40
  • Working with storage consumes less power than user interacting with the device. Stop treating android like some sort of precious flower and unleash the full power of the platform. – Eugen Pechanec Oct 03 '16 at 14:15
  • We don't want to treat it that way, but users are harsh. They want plenty of cool features but can't accept increasing power consuming and network traffic. But still thanks for the advise. I was working on it two days ago. – Kimi Chiu Oct 04 '16 at 02:39
  • This appears to be a duplicate of https://stackoverflow.com/q/39098590/5635880 – Brian Yencho Feb 23 '19 at 20:05
  • @BrianYencho No, it's not. Please read the question itself, not just the title. The `setRetainInstance` is not working after the app is killed by Android system. Another answer seems like answered my question but it was answered on Jun 24 2017. But my question was posted on Sep 29 2016. I'm asking "how" to store large data set in bundle. Another question is asking "why". And the answer to save large dataset is to save it in database not in the bundle. But still, the transaction size limitation is still too small. – Kimi Chiu Feb 24 '19 at 16:40
  • I did read the whole thing and the answers can be found in that other issue. I'll post an answer below, but to summarize : the "Application instance" only exists as long as your process does, which won't help you restore data after process death. This is also true of the setRetainInstance option on a Fragment : it only applies while the process is alive and does nothing to solve the restore-after-process-death problem. If you're looking for a way to save as much data as you want in a Bundle without throwing TransactionTooLargeException, check out github.com/livefront/bridge. – Brian Yencho Feb 24 '19 at 19:19

1 Answers1

0

To answers these questions one by one :

  • Is it safe to save instance state in Application instance?

Not if want to retrieve that data after your app's process has been killed by the OS and later restored. For that, you need to persist data to disk somehow. There are always two parts to properly handle saving state : handling configuration changes (like rotations) which do not involve process death and actual process death and restoration. Putting state in the Application instance (or any singleton) solves the first problem but not the second.

  • Will it be deleted while the Activity is in background?

Depends what you mean by "in the background". That can sometimes mean "the Activity exists but is in the stopped state". In that case, your data is fine. But your entire app process can be killed while the app is backgrounded and later restored when you return. In that case, your data will be gone if it is not properly saved to disk somewhere.

  • Is there a way to save large data without throwing this exception?

Yes, write it to a database and restore the data from there instead. Alternatively, you can use this library that automatically handles persisting / restoring your Bundles to / from disk for you : https://github.com/livefront/bridge .

Brian Yencho
  • 2,748
  • 1
  • 18
  • 19
  • Although I had resolved all these issues 2 years ago, still thanks for the answer. Didn't know there's a library for handling Android's limitation. I'm now restoring data from Realm database. – Kimi Chiu Feb 26 '19 at 15:08
  • No problem. And using a Realm database is a great way to go. – Brian Yencho Feb 26 '19 at 16:05