There has been instances where we need some code must be executed at the end no matter what happens to the application. Is there any way we can achieve the finally() functionality in Android?
Note: OnDestroy will not be called during the crash.
For the matter of fact even finally() is not a full proof method when the JVM exits. But in Java we do not see too many JVM exits. But in android since we have a DVM for every app process, we need a way to execute the final code else, we end up leaking the memory and battery consumption shoots up.
You can't leak memory when the application/vm crashes or is killed. In that case, the process is gone and any memory associated with it is gone.
If you are talking about allocating and freeing memory that's in a different process, you can get a Binder from the consumer process, and then use the Binder.linkToDeath functionality to receive a notification when that process dies.
Your best bet would be to run the cleanup operations in the onPause() of every Activity individually.
There is nothing like finally() in Android, as when an app crashes the entire process is simple terminated. Even normal methods like onPause() aren't called. Everything included in the process (Activities, Services, Receivers, Threads etc) is completely killed.
I am not sure what you mean by a leak here when your original process is anyhow not running.
Still one thing we did to handle such scenarios is to have a 'watchdog' process, though we had to do this in native code running in Android.
In your case, you could potentially create a service and make it run as a sperate process by specifying the
android:process=":remote"
flag in your manifest file. Now that service can potential watch for the main application process and do some cleanup if possible. Ofcourse you would need a way for the service process to know about which elements to clean up.
Hope this helps.
There are various ways to die:
Killed by system. Shouldn't happen while you're in the foreground, so make sure you close stuff as part of the Android lifecycle.
Fatal exception. You can deal with this by using a global uncaught exception handler. See Ideal way to set global uncaught exception Handler in Android
Native crash. Not much you can do about this. In some cases you can try to recover with a signal handler, but the app will be in a very uncertain state, so it's generally a bad idea and unlikely to work.
Looking through some of the other comments, it sounds like your device has a bug in the Camera driver that is causing it to be held open even after the process that opened the camera has died. This is a system bug -- the app shouldn't have to manage system resources when it crashes. (But, until it gets fixed, you've got to work with what you're got.)
Related
Is having a foreground service protective for the entire process? The documentation is a bit unclear, saying the service is highly unlikely to be killed. However, I've learned there's a big different between a service (or an activity) being destroyed versus the process (which contains all the activities and services, unless you are specifically forcing your service to be in a different process) being killed.
Any ideas?
Thanks.
First off, nothing prevents a process from being killed, and unfortunately there is very little you can do about it. Android uses a modified form of Linux's "out of memory" process killer to periodically kill processes. Memory does not even have to be low for a task to be killed - it can simply have been running for too long. If you are root you can fiddle around with various files (under /sys or /proc, it's been a while since I have looked at this) in order to fight Android and try to keep a process from being killed, but unless you touch these files very rapidly (several times a second) Android will still likely to kill your process at an inopportune time.
Having a foreground service won't change any of this, it will merely bump your process to a higher priority so Android is more likely to kill other things first. But depending on what else you are doing it may still have little effect. For instance, I have a logger app which I wrote which takes 12-15MB of (non-shared) memory while running, and when foregrounded it still gets killed on a device with 512MB of RAM if I switch to (memory hungry) Firefox and do much of anything. Note that there are things you can do to recover from this, for instance, telling AlarmManager to send you an intent periodically, which if your service is killed will restart it. This will increase battery usage, however.
Now with regards to the Service itself versus the Activity class, Android can very well garbage collect your Activity after calling onPause without killing the process. In this case, for example, if you have a pointer to your Activity from your Service class you will find that it is suddenly null, so if you are referring to your Activity in this way you should always test for a null pointer before trying to call into a non-static member of your Activity.
I have a simple app with native code. That is, an Activity plus native code.
When the activity is entering background, I keep the native code running to do some processing. The problem is when the activity is killed by OS (due to low resource), JNI code seems to have no knowledge of what happened in Java land and still doing its job, hence wasting resource. Why does Android kill just the Activity instead of the whole process? and in this case, how does native code know that the activity was killed? OnDestroy() may not get called.
An Activity in an Android application is described in the documentation as
An activity is a single, focused thing that the user can do.
It is usually something that is visible on screen and has the user's attention. It has associated with it a state-machine that describes the life-cycle of being shown and hidden when another activity become active. The operating system is at liberty to start and stop activities as it choses - and memory permits.
In addition, a key point of the Android architecture is that activities and services are reusable software components and do not necessarily have a one-one relationship to processes. Inside the same process as your activity may be a service in use by another process in the system.
If the JNI portion of your code is still active in the background when an activity has received an onPause(), onStop(), onDestroy() notifications, it can only be because you haven't forwarded these messages to it. The system certainly doesn't know how to clean up native code's resource utilisation - particularly memory allocated with new() or malloc(). Unless you free it, it will only ever be recovered upon process termination.
If your concern is that your activity is not being killed fast enough by the system and as a result holding references to resources in native-land, it's a good sign that the system isn't resource limited.
You might consider implementing the native portion of your application as a Service and have it self-destruct after short periods on dis-iuse.
You could have multiple Activities in one Android Application. As your Activities go into the background, they can be killed to reclaim resources. The application is typically kept around until the phone runs really low on memory, or the user goes and kills your app manually. The process sticks around until the application is killed, roughly speaking.
Because you can continue processing in the background, when your Activity is re-created you can check the status of your global variables and perhaps pick up where you left off.
Keep in mind that Activities are killed quite often, so there's not much point to doing processing in the background but stopping when the Activity is killed. You might as well stop when onStop() is called in this case.
I am investigating if there are any ways to prevent an android service being killed because of uncaught exception.
We have 10 UI apps talking to 5-6 services. The platform is Android 2.2.
Because of unforeseen conditions, some of the logic in the services are throwing exceptions now and then. That is causing those services getting killed with those annoying ANR popups.
While we work on a solution that fixes the root cause of those exceptions, I like to prevent Android from killing the offending service.
It looks like I can register Uncaught default exception handler for all the threads in the services. That just gives me an opportunity to log something about the exception. That is good.
I came across many postings that used this technique to log the crash info to a file for later use.
People suggested not to throw the original exception to prevent the ANR popup. I also found some articles that suggested it can leave your service in half dead state. The right thing to do is kill the service and restart. Killing and restarting is not an option I am interested in.
I didn't quite understand the half dead state part if you don't throw exception. I am going to investigate further. Meanwhile I am wondering if people have suggestions.
My goal is to prevent ANR popups. I want my code to make the decision whether to restart a service or not instead of Android framework deciding it for me.
What I am curious to find are:
1) Is there any flag in manifest you can change to prevent services from getting killed by framework code?
2) Are there any methods you can override in a Service that lets you handle uncaught exceptions, but still let the service thread to go back to waiting state for the next request from a client?
Thanks for suggestions.
Videoguy
Update:
The Uncaught default exception handler doesn't help here. It gives you an opportunity to log something, but the service thread still exits.
You need to change android framework so that it doesn't kill processes. ActivityManagerService.java in android framework has different thresholds how long a service can run without any clients, how many background activities/services you can have, timeouts for service and ui initialization. We bumped those values up.
One common way that developers help keep their services from being killed is to use a persistent notification (in the notification bar), which is usually toggled on through settings. So, if the user is having problems with the system killing the service, they can toggle on the notification.
Is there any flag in manifest you can change to prevent services from getting killed by framework code?
No.
Are there any methods you can override in a Service that lets you handle uncaught exceptions, but still let the service thread to go back to waiting state for the next request from a client?
No.
I am developing an Android application, and when I start my application 2nd time I am getting force close error. Following is my logcat:
06-07 16:08:12.763: ERROR/AndroidRuntime(3293): Uncaught handler: thread exiting due to uncaught exception06-07
16:08:12.773: ERROR/AndroidRuntime(3293): java.lang.NullPointerException06-07
16:08:12.773: ERROR/AndroidRuntime(3293): at com.androidpeople.tab.MobiintheMorningActivity$t2.run(MobiintheMorningActivity.java:209)06-07
16:08:12.773: ERROR/AndroidRuntime(3293): at java.lang.Thread.run(Thread.java:1060)
Your logcat capture is telling you that in your source file MobiintheMorningActivity.java, at line 209, you're using an object which is null. Seems pretty straight forward.
To prevent the application from crashing place try{//insert code} catch(Exception e){//todo when something fails}
On the NullPointer, try debugging your program and locating the null
Huh, I feel that I should give some more useful comments than those stupid answers from Captain Obvious fellows. Usually such problems happen because developer doesn't fully understand Android Application life cycle. When you start application second time, actually you re-starting an Activity, not whole Application, so for example static data may remain from previous activity launch, even you received onDestroy() event for that activity. If you created any threads, they may remain alive (if you don't take special actions to stop them gracefully, which is not often a trivial thing - for example in my case a thread was reading data from InputStream.read(), a blocked call ending somewhere in native code, and it was not possible to interrupt it, either via Thread.interrupt() or via InputStream.close() called in other thread. But it is another story).
So, from design point of view, if you're using threads, you must keep in mind that you may be attempting to start a new thread while the old one hasn't finished yet.
Whole application will be fully destroyed when OS decides so, when it will need to recycle memory. If your app is running some threads in background, the app may be considered alive, even you do not have open activities at the moment, and the app may avoid recycling, causing some sort of memory leak. This is considered as a bad coding style.
In your case the thread seems to reuse some old data, which you probably expected to be re-initialized by Activity re-start. Or you may have another thread concurrently running from previous launch and sharing data with Activity being started second time, and it reads/writes data while you're initializing them in the second start of the Activity, for the second start of the thread.
So you need to make sure that you do not start another thread before the first one quits. You may consider using a Local Service for such purposes, but you would need to launch threads for background activities (to not perform them in main event thread of the application, which is common for services and activities in the same Application instance), or in AsyncTask. A Service simplifies things a bit because it is not interrupted by Activities start/end, so you can somehow handle an async process (in your thread) between activities restarts. So activities should put requests to service to perform long jobs, and query its state from service (or receive notifications, for example via listeners, which quite OK for local services). So, starting an activity, you should check what the server is doing - probably it already performs a job from previous activity start. Your activity may request to stop the job (if you already didn't do so when previous activity finished), and wait for job cancelation, which generally may be not a quick thing, and should be made asynchronously). Of course you may implement the same approach without a service, just in that thread.
I have an application that I suspect might be leaking a thread or its context. What makes me think so is that after closing the app, the process is still running (visible process monitoring applications). I've cut everything in the code, going as far as calling finish() from the onCreate. The process is still around and annoying me.
I've read that (from here)
An empty process is one that doesn't hold any active application components. The only reason to keep such a process around is as a cache to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.
How do I know if my process is still around because of circular reference or context leak or anything else equally bad or if is simply that the process is empty?
The fact that you still see the process will not give you any information about the existence or not of references to objects in your application. There's no magic that's going to answer that for you.
If you are worried, you should inspect where (if anywhere) you are registering callbacks (AKA listeners) with system services. This is a common root cause. the correct pattern is to register in onResume() and unregister in onPause(). You are guaranteed those will be called when your app pauses / resumes.
Unless you have a really special purpose reason, don't as suggested above use the various methods for manually killing your process. The OS has memory management built into it. Don't try to be smarter than the OS. Android keeps application artifacts (activities, services, etc) in memory even when they are "finished". This allows them to re-start faster the next time. If it needs the memory for something else, it will remove the unused processes from memory.
How are you closing the application? Hitting the back button or the home button doesn't close the application, it just finishes (or pauses) the activity. You have absolutely no control over when Android decides to terminate the process and kill the application.
finish() doesn't actually kill your application. In almost every case it's the exact same as if the user had hit the back button.
ActivityManager.killBackgroundProcesses(yourPackageName) may be what you're looking for.