0

If I have a class that contains a static variable, say x:

class MyClass {

    static boolean x = false;

    // Other methods

}

Now let us say that, hypothetically, I set x = true; from my first activity. Is there any point through the rest of my app's life cycle (including various activities and threads) where this value will simple be 'reset' back to false due to how the 'Google JVM' or the android environment works? I have heard that static variables have a 'lifetime', that dies when the program dies. Do Activities count as separate 'programs'? What about services? Or even Widgets?

I am asking this because it is often difficult to share complex data structures that rely on other complex processing (like syncing data from an online database) in android due to how 'separated' activities are, and static variables are often a very quick and dirty solution to the problem. Other things I have tried include serialisation, but that doesn't really seem like a practical solution either (constantly serialising and decoding objects when the user navigates from one activity to the next seems like it would be very resource intensive).

If I am an evil person for doing this, please tell me what I am doing wrong, or even better, give me some links or examples of better ways to solve this problem.

otoomey
  • 939
  • 1
  • 14
  • 31

4 Answers4

1

Yes. There are times where that will reset. Primarily if the user leaves the app and starts fiddling around with other apps or if the user lets the phone go to sleep for a long period of time. The Android process could kill the actual app. Then the "state" of the app will be restored when the user comes back, however static variables will be at their defaults because the actual process was rebuilt.

Generally passing small objects between Activities and Services is done by overriding the Parcelable interface. This will allow you to save and restore objects using setOnInstanceState methods of both Activities, Views, and some adapters. They will likewise, have a restore method in which you can rebuild the object. Parcelable is preferable over Serializable.

Larger data may require a shared file or database depending on the data that you want to have synced. There is a 1 MB size limit for parcelables being passed between Activities. One common tactic is to save the information to a file and send a URI to the location of where the information can be retrieved.

Community
  • 1
  • 1
DeeV
  • 35,865
  • 9
  • 108
  • 95
  • since this is the answer to my primary question I consider it be the final answer. Thanks to everyone for contributing. – otoomey Mar 01 '17 at 20:32
  • @Campbell: It is annoying having to deserialize/reserialize everything constantly. It usually does not take very long (milliseconds at most), but if it's much longer (i.e. very large images), then you may need to consider restructuring and breaking down the data or not using multiple Activities at all. `Fragments` can often be used in a single Activity and it's far easier to share data between them. – DeeV Mar 01 '17 at 20:39
1

Answering your question - yes, there is a situation when you set x = true and value will be 'reset' back to false. Well, not exactly reset but consider this scenario: you have an activity and a service. Service is using separate process (you can define that in AndroidManifest when you declare your service). Then those two processes (main app and service) won't share memory and setting x to true in your activity won't affect the value of MyClass.x in your service. In all other cases changing value in one place will be visible everywhere else. Hope it helps!

0

No, a static variable will not be changed unless you change it or the app ends, it is safe (but generally unclean) to use it. Closing the activity the variable lives in won't hurt it.

You suggest you just need to keep track of a value as you move around activities. In that case you can add the value in your Intents as what is called an 'extra'. If you need to also pass back the value after, android also has the startActivityForResult feature

Intent extras example:

x below could be any type of value including any object which implements Parcelable

Intent intent = new Intent(...);
intent.putExtra("myKey", x); 
startActivity(intent);

in receiving class:

x = getIntent().getBooleanExtra("myKey");

Edit:

Given your additional comment - "lists of objects that contain yet more lists of objects" you may get a Parcel too large exception when trying to use extras, but this is an indication you have a bigger architectural problem and that there may be a better approach

Nick Cardoso
  • 20,807
  • 14
  • 73
  • 124
  • I'm sorry it isn't clear in my question; to rephrase: Intents only allow you to pass primitive datatypes between activities, but I want to access huge lists of objects across my app. – otoomey Mar 01 '17 at 20:16
  • No they don't. Not at all. They support lists, custom objects, primitives... even lists of custom objects containing other custom objects – Nick Cardoso Mar 01 '17 at 20:18
  • yes but that is effectively serialisation, but instead of you doing it explicitly, android does instead. https://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String, java.io.Serializable) – otoomey Mar 01 '17 at 20:21
  • It is, yes, but much much faster http://www.developerphil.com/parcelable-vs-serializable/ – Nick Cardoso Mar 01 '17 at 20:25
0

Use Gson. Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

You have two options. Convert to string , then put data in an intent then pass to activity. Or Convert to string with gson, save to a preference, then in the other activity, check if the preference is alive and read from it.

If you wish to be bold, you can persist to database preferably using Realm for Android or ObjectBox is a new mobile object database optimized for performance. With ObjectBox, we are bringing technology from NoSQL server databases to mobile.

Remario
  • 3,813
  • 2
  • 18
  • 25
  • Doesn't this take ages if I have a lot of data? – otoomey Mar 01 '17 at 20:17
  • define alot? above 30mb – Remario Mar 01 '17 at 20:19
  • Then the second option is the way to go, convert to string, save to a shared preference, and collect in the other activity. – Remario Mar 01 '17 at 20:20
  • This works, tested it with base64 image, and you know that base64 encoding a image is very large. – Remario Mar 01 '17 at 20:22
  • How long did it take? milliseconds or seconds? – otoomey Mar 01 '17 at 20:25
  • testing took little over 1 second with a 5mb image – Remario Mar 01 '17 at 20:26
  • did you run it on a phone, emulator or on a computer? If a phone, which one? I'm worried that older devices could struggle and make the app sluggish. – otoomey Mar 01 '17 at 20:28
  • alcatel idol one touch physical and used geny motion for emulation. there was consistency across all benchmarks. ObjectBox is new and super fast if you dont want shared preference and gson serialization. Either way the end result is good. Go test it for yourself. – Remario Mar 01 '17 at 20:30
  • do you dislike my answers? – Remario Mar 01 '17 at 21:02
  • no, but I can only chose one answer, and while you answered my secondary question, Deev answered my primary question. I learned more from yours, however, and about the real-life speeds of serialisation. – otoomey Mar 02 '17 at 17:46