Issue
Problem: Sometimes / on some devices the activity calling startActivityForResult (activity A) to launch activity B is being destroyed after calling startActivityForResult & before entering onActivityResult. We get a newly created instance of activity A to return to in onActivityResult - this causes our ViewModel (along with all other member variables) to be lost.
The standard thing to do would then be to restore the ui state using SavedInstanceState. This can't be done in this case due to the size of the object we need to restore - attempting this results in a TransactionTooLargeException. The ViewModel is too large for a Serializable or Parcelable.
Question: Is it possible to force our Activity to be kept intact during this workflow? Or is there another design that would let us avoid this problem? Saving any of the ViewModel's data to disk is not an option.
Context: This is a project where we store a list of images (as byte arrays) taken from the camera one at a time, and some related info about those images in a ViewModel. These are staged in a RecyclerView, where they can be uploaded when the user is done adding images. We add items to this ViewModel by calling startActivityForResult to launch a camera activity and return the resulting image.
We may only be seeing the problem of activity A getting destroyed due to the "Do not keep activities" setting in Developer Options being turned on, and this may not accurately represent how Android would reclaim resources (e.g. the conversation at the bottom of this thread - https://stackoverflow.com/questions/21227623/whats-the-main-advantage-and-disadvantage-of-do-not-keep-activities-in-android#:~:text=Android%20OS%20has%20this%20property,replicate%20the%20same%20scenario%20easily). Still, ideally we want everything to work with this setting on. Right now if activity A is destroyed, we lose our member variables and the ViewModel that we were in the process of building, and don't have a way to recover it.
Storing the ViewModel's data in a fragment (as discussed here: Fragment, save large list of data on onSaveInstanceState (how to prevent TransactionTooLargeException)) won't work since our activity is being destroyed, causing any associated fragments are as well. We actually have a fragment we're using in this way, which loads & holds a list of objects from the server to be selected from and associated with each image - this fragment ends up getting recreated along with the activity when its destroyed and then performs this load again.
Solution
No, what you want is not possible. If you launch another Activity
using startActivityForResult()
and that Activity
requires resources, the launching Activity
will be killed. There is nothing you can do to prevent this. It is standard Android behaviour and will happen, especially on low-end devices.
If your ViewModel
is too large to save as the instance state, you will need to put the data somewhere else: SQLite database or a local file. Then store the name of the file or some key to the database as part of the saved instance state, and when the Activity
is relaunched, restore the data from the file or data base.
Note: you shouldn't keep that much data in memory anyway, as you are wasting valuable resources. Only keep the data you really need in memory.
Answered By - David Wasser
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.