I have an activity which is basically a tabbed activity for keeping a score a of cards game.
The problem is that, when I get phone call and I come back to my app, then the score is cleared!
It seems like activity is restarted a phone called is received. Why is this happening and how can I fix that?
Thank you
Android devices had limited memory, and can only run so many apps at once. Phone calls are one of the most taxing tasks on a mobile's hardware, as audio streams aren't exactly small on memory usage.
Due to this, I think your app's current instance is killed to free up RAM, and this results in a loss of scores for you.
To fix this, you could write the value of the scores to SharedPreferences in your Activity's onPause() and then retrieve them in onResume().
Related
I have an Android app which listens to a port and updates the screen based on what it hears. This works flawlessly. The problem happens when I leave the app running for say 20-30 mins. During this time the screen would have gone blank for power saving (display). After this point, the app either becomes unresponsive or totally hangs. I doubt if it's memory leaks. Can't figure out how to go about debugging this issue. Any pointers? TIA
May be there are variables that are lost, try to save and restore the state of your Activity using the methods onSaveInstanceState() and onRestoreInstanceState().
check https://stackoverflow.com/a/151940/1434631
I was building a widget for android and same thing was happening to me. I believe the problem is that process is destroyed and started again from time to time, and then all your variables lose value. You should use content provider to store them and then obtain them when lost.
It seems that there is a large amount of information about saving Activity state, but I have been unable to locate much on finding Application state.
I am looking for some design ideas to solve a problem I have run into. I am developing a game that has a fairly large data model (1-2 MBytes). This model exists outside of any Activity, in fact there are numerous activities that all interact with it. These activities are transient, coming and going all the time.
I currently keep a pointer to the data model in my application and all of the activities access the data model through it. I need to save that data model in the event that my application is being killed, but it is far too slow to save it every time an activity hits onPause, which happens very frequently as activities come and go.
What I need is a way to determine that my application (and along with it my data model) are being destroyed. I have searched extensively for this method or callback and have come up empty.
I would appreciate any suggestions.
I have been unable to locate much on finding Application state.
That's because there is no "Application state" in Android, any more than there is in a Web app.
but it is far too slow to save it every time an activity hits onPause
While your entire data model may be "1-2 MBytes", but the amount of data that changes is going to be a small subset of that, for any given change. Use a background thread and only modify the data that has changed.
which happens very frequently as activities come and go
It sounds like perhaps you have too many activities.
What I need is a way to determine that my application (and along with it my data model) are being destroyed
That is not possible. You will never find out that you are being destroyed. Android can and will terminate your process without warning, either at user request (e.g., Force Close, task killer) or for OS reasons (e.g., need the RAM to handle an incoming phone call).
You are welcome to use onUserLeaveHint(), which is called in a number of cases when you entire app loses the foreground, but I certainly would not count on that for something as important as persisting a data model.
I have an app which let users to pick an image from sd card and then app process the image. I am downsizing images to 1/5 of avialable vm memory and i do call recycle() for every bitmap in onDestroy() call and i still get out of memory error if i close and open my app multiple times.
There are various memory leak scenarios in Android. One way to track them down is to use the Traceview tool http://developer.android.com/guide/developing/debugging/debugging-tracing.html.
For more info on common Android memory leak problems see http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html
Note that when you finish the last Activity of the app the Java process of your app may (in most cases will) be alive meaning all static stuff is still alive when you "start" the app again. Do you store any heavy objects in static fields?
Also note that according to the Activity life-cycle the onDestroy() is not guaranteed to be called. However I don't think this is related, because when you (versus the OS) close the Activity (either by pressing 'Back' button or by calling finish() from the code) then OS always calls onDestroy().
In general, without seeing the code it is difficult to say what happens.
I understand why an always-on service is normally an anti-pattern in Android, but my app really seems to be begging for one:
On first load, the app has to go through potentially thousands of small entities from the database to construct the initial state. There's not much data brought into memory (most is lazy loaded later), but that first scan is unavoidable by the nature of the app. This scan can take at worst 6-7 seconds with slow hardware and a big dataset, average is probably around 3. The app is a "impulse use in short bursts" type of thing, so those repeated loads are really not desirable.
I think this begs for a background service to be perpetually alive and holding that state, thus avoiding that load time. It will always be ready to be killed, and not in the foreground, so should the system or user decide that they have it out for the service, no harm is done. But if the service is left in peace, the app will start instantly, and in my case that does a lot for the user experience.
Am I still wrong?
I think this begs for a background service to be perpetually alive and holding that state, thus avoiding that load time.
As the British say, bollocks.
On first load, the app has to go through potentially thousands of small entities from the database to construct the initial state.
Then fix that. Either simplify this work, or persist the initial state in a simpler form for later reuse (e.g., JSON).
If it is OK for you to use a cached result of this work that is held in RAM, it is OK for you to use a cached result of this work that is held in an easier-to-read-in persistent data structure.
An "always-on" service would essentially act like a daemon process and there are plenty of services on Android phones that never turn off.
In this case, though, it seems a better solution would be to simply have a splash screen and/or wait dialog that sits there until the data is loaded. It seems like a bad idea to me to take up resources when the app isn't running just so the app will load faster when the user finally opens it. If the average use of the app is much smaller than the load time, then it would probably be even better to speed up the scan in some way.
People use taskkillers to kill such kind of services. My view is, that when you make the user aware of why your service is running (say, this will load the app quicker), he will understand it and not kill it. You could also ofcourse add an option to use the service or not.
I'm building an Android application that's based around an enhanced WebView (based on PhoneGap). I've enhanced the WebView so that from JavaScript running inside you can invoke the native contact picker to choose a phone number (which may be supplied by Facebook for example).
The problem I have is that the native contact picker runs in an activity in another process and the Android docs say that while another activity is open my activity may get destroyed due to memory constraints. I haven't actually seen this happen in my application but if it did then I'm guessing my WebView's state would be destroyed and the code that was waiting for the picked contact would be terminated.
It seems a bit crazy that the activity requesting a contact could be destroyed while the contact picker is open. Does anyone know if that does indeed happen? Is there a way to persist the state of the WebView if it does?
Thanks,
-Shaun
Does anyone know if that does indeed
happen?
You're looking at the problem too simply.
You have a WebView. You open the contacts application. While the user is in the contacts application, a phone call comes in. While on the phone call (using a Bluetooth headset), a text message comes in, so the user opens that up from its Notification. While still on the phone call and texting away, a text comes in with a link, so she taps it and brings up the Browser application.
By this time, your activity is surely destroyed, except on maybe some of the most recent phones that have a fair bit of RAM.
Now, is that common? No. However, this also has nothing to do with the contacts application -- if the user presses HOME, at some point in the future, your activity may be destroyed to free up RAM as well.
Is there a way to persist the state of
the WebView if it does?
That depends on what you consider "the state of the WebView" to be. This really is PhoneGap's job, if you are making a PhoneGap-based app. So, you might consider asking them.
There is no way to persist the DOM. There are trivial ways to persist the URL (see onSaveInstanceState()). And there may be stuff in between that you consider part of "the state of the WebView" that may or may not be possible to save.
The long and detailed answer is a bit complicated, but essentially it comes down to a few points:
If the Android OS has to go cleaning up Activities or Services, it knows how to prioritise which ones should go first. It does this based on whether they're currently in the foreground (last to go), in the middle of executing code, waiting for a result, or simply sitting inactive in the background (first to go). You can be reasonably certain that if your WebView Activity launched the contact picker using the startActivityForResult, it won't be killed
There's a whole system for saving data if an activity is killed, such as the onPause method (which are triggered as soon as your activity leaves the foreground), the onSaveInstanceState method which is called when your activity is about to die. Read up on those to get more information, and the configurationChanged method when the screen orientation changes. If you haven't at least skim read the Activity Lifecycle document on the developers page, you must do that.
Lastly, I'm sure this question has been addressed many times, but with slightly varying wording or situations. Have a look around, see what else you can find.