I have a pretty extensive adventure game running on Android using flixel-gdx, and I would like to save the current game state when android switches to another application.
I know you can override the onFocus() and onFocusLost() methods on the FlxGame object, but I can't see a way of accessing the current game state from those methods. The only way I can see is to create a static object that holds a reference to the game state values, and refactor my entire game to reference the static object when it needs to manipulate those values.
Can anyone think of an alternative?
FlxG.getState();
returns you the current state that is running.
I am new to android development (and also a java newbie) and I noticed that when I switch between views I noticed that any variables declared as static in the view class retains its value but the rest are gone. So I have the following questions if some one is kind enough to answer --
When to use static for variables if any?
If I want to retain the state of say my game between these switches (say to see the score or something), what is the way to do it? Is it by using static variables in the class to store everything? If so how do I reset the variables for a new game?
When to use static for variables if any?
Static variables should be use when multiple activities needs access on it. In other words, if you think your variable has global usage, then setting it as public static may help.
If I want to retain the state of say my game between these switches (say to see the score or something), what is the way to do it? Is it by using static variables in the class to store everything? If so how do I reset the variables for a new game?
You need to override onSaveInstanceState and onRestoreInstanceState to save and restore the values of your variables. A tutorial on how to use it can be found here: http://android-er.blogspot.com/2011/09/onsaveinstancestate-and.html .
I need to pass a List of my objects between activities. I do not want to use parcelable or serialize the data each time. I also do not want to save it in a local file or database. That probably leaves me with using static objects.
Lets say I to use ListA between activities Activity1 to Activity2. I ca
Approach1: Create a static ListA in one of those activities and do all my stuff of that static ListA.
Approach2: Create a static list in another class which I use just for storing this List and doing all my stuff on this list. But this means that this stays as long as my process is running and I have to manually set it to null when I do not need it.
Approach3. I am extending the above class to implement it using a static HashMap.
I have two methods one to store the list in a static HashMap using a unique key and another method to retrieve the list and remove it each time data is retrieved so that the List is no longer present in the static HashMap. So we essentially have to pass only the random key generated to store data between activities which I can pass as an extra using Intents.
Will there be any issues when I use any of the above approaches and which will be the best approach.
I'd consider creating an Application object and using it like a singleton to access your data. I've described the approach here: http://chrisrisner.com/31-Days-of-Android--Day-7%E2%80%93Sharing-Data-Between-Activities. Some people don't seem to like using the Application object in this manner but it makes more sense to me than putting a static object on an Activity.
Uggg statics! Man I wish all developers understood global variables are bad and how they make your program more brittle and your life hell. We only been talking about how bad they are for 30+ years, but unfortunately no one figures this out until they've utterly hung themselves on them.
First I'll say serializing your data is fast. There are great tools out there that will serialize your objects quickly that you can use I prefer http://flexjson.sourceforge.net for this.
So if you are just outright opposed to this you can pass this object through the Application by subclassing it, declaring your implementation in your Android Manifest, and each activity has access to the Application instance:
public class MyActivity extends Activity {
public void onCreate( Bundle bundle ) {
MyApplication application = (MyApplication)getApplication();
Object anInstanceFromAnotherActivity = application.getSomeInput();
}
}
The downside to this is when your application is reclaimed if the user returns to your application the memory is gone, and you can't get that input you might need of your screen. Android framework is trying to make you serializing things in the bundles because if it decides to destroy your application you can always rebuild yourself from the bundle. Now there are short cuts you can take like redirecting people to start over if the Application has been reclaimed, but those depend upon your program and what its doing if they make sense.
That's where using serialization wins out over all other forms of persistence (parcelables, files, databases) because it can be done in one line of code.
i am new in android and java ... i am reading from couples of day about android parceling tutorial for transfer data or variables values from one activity to other or one class to other ... but i am not so understood about that.
can u tell me that is it necessary to use Parcelable for this purpose because same task can also be perform using static key word for variables as string,int or array type then why parcelable pls explain in detail ..
thanks for explanation in advance please provide comparison with example
While technically both approaches will work, there are a couple of flaws.
The first is that the static variable is static. If you have two instances of the same activity, they will both reference the same static object. This is probably not what you want.
Secondly, it's considered bad practice to access global variables. It makes it difficult to see what is going on, is difficult to test and you someone (another class) can modify your data. This creates some horrendous bugs.
By passing the data via a Parcelable object it is very clear what you are doing and you avoid both of these problems.
Note that this advice is not specific to Android, rather to Java and programming in general.
Static references never get garbage collected so you end up creating something called a memory leak.
You are keeping an object in memory that you don't need and it can't be freed up.
If you instantiate enough objects like this you will get an out of memory (oom) exception which will cause the app to crash.
I have an application which has some static variables.
These variables are stored in an independent Class named DataContext.
These variables are initialized from raw files at the application start (a method named DataContext.initConstant() is called in the onCreate() of MyApplication which extends Application).
(EDIT : the initConstant method use an AsyncTask to load this data from files).
When my application comes to the background for a certain time or when my application used to much memory, these static variables become null.
How can it be prevented?
If not what should I do with my static variables?
I have other data which are stored in static variables to be used across different activities, but I clear them or pass them to null in the onLowMemory() of MyApplication.
What is the best way to keep some data accessible between activities if these data are too big to be serialized in an Intent, a database can't be used (for whatever reason), and can't be stored in files through serialization either?
You can't. Android needs to free up memory from time to time. Imagine if all applications had a ton of static data that is supposed to be resident forever - how would you fit that in memory? It's a mobile phone. It doesn't have virtual memory.
(and 3): Anything that is intended to be persistent needs to be stored, either via SharedPreferences, a Sqlite database, or a file.
Most likely the issue is that your application is being killed while it is in the background, and then recreated when you come back to it. Check out the Activity Lifecycle documentation on when this might occur for a single activity. You need to make sure that you move anything stored in memory to more permanent storage at the correct point in time to avoid losing that information if the app gets killed.
I'm not sure what exactly you are storing, but it sounds like using Shared Preferences might work well. This page on Data Storage explains a number of different ways of more permanently storing data, including Shared Preferences.
If you weren't using raw files, I'd advise initializing when the class is loaded.
For instance,
public static Map<?,?> myStaticMap = new HashMap<?,?>();
static { //fill myStaticMap }
You do have some bigger concerns to worry about if you are loading files that way. For instance, what about I/O errors, or latency issues? You will get warnings in gingerbread (if you enable them) for doing I/O in your main thread. Perhaps you should have an object to retrieve these values instead of a class with static fields. (perhaps with a static cache, although you should synchronize on it before checking/changing it)
I assume this is a data cache problem.
Storing data in static class is not guaranteed to work when user swap apps often. Android system will reclaim any background activity when memory is low. Static class is definitely among this category.
The proper way to do it is to use sharedPreference to persist cache data.
You can create your own getter and setter of the data you want and wrap it around sharedPreference object. When you access using getter, you should always check if the value is empty or expired. You can store an update_time when using setter.
For activity specific data, you can just use getPreference(permission), if you want to share data across activities and other applications components, you can use getSharedPreference(name, permission).
Normally, the permission will be MODE_PRIVATE such that the data can only be accessed within your application.
You should group data and store in difference sharedPreference object. This is good practice because when you want to invalidate that group of data, it is just a matter of one liner.
editor.clear(); editor.commit()
If you want to cache complex object, you should serialize it. I prefer JSON format. So you need some conversion mechanism in place. To do this, I will create my data object class extending JSONable class. JSONable class will have toJSON() method and readFromJSON(). This is convenient when restore and serialize data.
I store a User object and a Client object in my static scope. I have noticed from time to time the reference becomes null. So now in my getters I check to see if this value is null and if so I restart the app.
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
I could have also chosen to reload the Client because I store the Access Token in prefs however I do so much initialization that I decided restarting the app would the best idea.
In your onResume() method you could query the static data to see if it is present and if not, load it back in again.
Instead of using the static variable u can use the shared preference for storing the value.
Note: for shared preference also you should not give heavy load.
I have solved this problem by having the super class with getter and setter function for storing and retrieving shared preference variable.
All class in my application extended the super class instead of activity.