1

I'm trying to pass large data from one activity to another. For business reasons, I cannot save this data to persistent storage and need it to stay in memory.

Up until now, I've been using Intents to pass Serializable data, but with larger data, I've been receiving TranstactionTooLarge exceptions/crashes.

What are my options? I am using Kotlin, so Kotlin-specific solutions are welcome.

I've thought of using Singletons, but I'm unsure of the side effects of that, or if there is a better solution.

user098765
  • 11
  • 2
  • 1
    Adding your code might help others. Assuming this data is for a View, you might want to investigate using a shared ViewModel. – Bink Feb 12 '20 at 19:28
  • 1
    You will find answer to your all questions related to TransactionTooLarge exception here:- https://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception – Satyam Kamboj Feb 12 '20 at 19:30
  • @SatyamKamboj I've looked through there already, nothing Kotlin-specific. – user098765 Feb 12 '20 at 19:39
  • What about randomly generating encryption key, storing encrypted data in temporary database and passing that key to second activity? Once key leaves memory it and all data become unrecoverable. – Pawel Feb 12 '20 at 20:53
  • Use a single activity and multiple fragments, for the screens that need to deal with this large data. – CommonsWare Feb 12 '20 at 21:19
  • @user098765 don't worry about the code in kotlin or java, just look for a solution there and when you try to implement that then compiler will automatically convert the code to kotlin or java as required. – Satyam Kamboj Feb 13 '20 at 03:02

2 Answers2

2

You can use singleton object and store your data in it. In intent you can pass some key (Int or maybe String) to get your data from singleton in receiver activity.

Also there are implementations of event bus pattern, that are applicable for same reason.

nsk
  • 310
  • 2
  • 9
  • Singleton is a pretty bad idea since you will lose all data if app process dies – danielctf Feb 12 '20 at 20:54
  • Yes, it is possible, but @user098765 told that it is the only option "I cannot save this data to persistent storage and need it to stay in memory." – nsk Feb 12 '20 at 21:08
  • 1
    I think this limitation may be bypassed with JobSheduler. So system can store heavy data in JobInfo, if process get killed before receiver activity started. But I am not sure about data size limits in this case and this seems to be very clumsy solution even if it works. – nsk Feb 12 '20 at 21:21
1

TransactionTooLargeexception reflects limitations of IPC mechanism on Android, in the way, how data are transfered between processes.

Since you are sharing data between activities, given restrictions you have, following possibilities came to my mind:

  1. keeping data in a singleton instance of repository (which takes reponsibility for reloading of data in case, they get lost during recreating of activities etc.) and trafering just unique indetifier(or identifiers)
  2. reduce size of data by simple data transformation or compression(integer instead of float, long for Date etc.)
  3. as pointed out by @nsk, with an event bus you can overcome limitations of IPC, but this brings a "fun" with activity's lifecycle
  4. kotlin brings kotlinx.serialization into the game, not much experience on my side, but sure something you can evaluate(performance and data size)

Independently of selected solution to your problem, I would recomend to use Parcelable instead of Seriazable for Intent, mainly for performance reasons, reflection is still an issue and I can barely remember having lint warnings. For Parcelable with Kotlin there is indeed a handy solutionwith Parcelize annotation provided by Kotlin Android Extensions library.

Simple object looks like this

@Parcelize
class Student(val name: String, val year: Int) : Parcelable
Michal Harakal
  • 1,025
  • 15
  • 21
  • I guess that data size limit apllies for parcelable the same way, its just recommended way to serialize (e.g. for performance reasons). I've just mentioned possible ideas. A solution and decision depends on kind of data and app itself. Regarding activities recreation, for example receiveing a call, phone rotation, app comming from doze mode, low memory etc. can lead to recreation receration of activities. I wanted to point on fact that data are kept in a memory as long as a process lives. – Michal Harakal Feb 12 '20 at 20:41
  • It is fair point about parcelable are not related to the solution, at least not directly. So I am more clear about it later. I also I don't have a clear favorit, it dependes on data I don't know, I just try to provideideas with solution. In my guts I would prefer a solution without moving data around. – Michal Harakal Feb 12 '20 at 21:17