Android activity lifecycle and JNI native code lifecycle - android

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.

Related

Why my app stop working?

I am developing a simple app that just play a white noise sound in background while I am doing other things.
It works very well when I switch to other apps ( like games, chrome browser, etc ) but sometimes ( for example when there are many chrome tab opened ) the white noise sound stop and I need to reload my app.
I am NOT using Services, is this the reason ?
Because your apps is getting killed by the system to give up resources for to other apps (games, chrome, etc). So you need to use a Service.
Here an excerpt from Processes and Application Life Cycle
for more details explanation:
An unusual and fundamental feature of Android is that an application
process's lifetime is not directly controlled by the application
itself. Instead, it is determined by the system through a combination
of the parts of the application that the system knows are running, how
important these things are to the user, and how much overall memory is
available in the system.
...
A cached process is one that is not currently needed, so the system is free to kill it as desired when memory is needed elsewhere. In a
normally behaving system, these are the only processes involved in
memory management: a well running system will have multiple cached
processes always available (for more efficient switching between
applications) and regularly kill the oldest ones as needed. Only in
very critical (and undesirable) situations will the system get to a
point where all cached processes are killed and it must start killing
service processes. These processes often hold one or more Activity
instances that are not currently visible to the user (the onStop()
method has been called and returned). Provided they implement their
Activity life-cycle correctly (see Activity for more details), when
the system kills such processes it will not impact the user's
experience when returning to that app: it can restore the previously
saved state when the associated activity is recreated in a new
process.
I think Services is What You are looking For.
A Service is an application component that can perform long-running
operations in the background, and it does not provide a user
interface.
For better chance of preventing OS to kill your app, you should use a
Foreground Service
following the official guide here: https://developer.android.com/guide/components/services.html#Foreground
Remember that there is no way to be certain that OS will never kill your app, because when RAM becomes really low it could kill every process indipendently from type, following his priority rules

Android process in background - it must remain always alive - sometimes it has to play sounds [duplicate]

I have a Service running in the same process as my Application.
Sometimes the Android OS decides to kill my service (probably due to low memory).
My question is: does my Application get killed along with the Service? or how does it work exactly?
Thanks!
First be sure to read: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
The key to this is that on Android a process is just a container for code -- or specifically one or more components (activities, services, receivers, providers). By default all components in a .apk get their own, dedicated process, that they all run in together. This is almost always what you want.
When the user is directly interacting with a component of that process (that is an activity) Android will try very hard to keep that process running, and you won't see it killed except under extraordinary circumstances.
When the user is no longer directly interacting with the process, then it becomes expendable relative to other processes as described in the referenced documentation. That is, empty processes (no interesting components) will be killed before processes holding activities that the user had been using, which will be killed before processes with running services. So having a running service will tend to keep your process around at the expense of other processes.
At the same time, we need to deal well with more and more applications leaving services running, often indefinitely, and often with memory leaks. So has a service runs for an increasingly long time, Android will try less and less hard to keep its process going. Effectively this means moving it down to the background bucket until the out of memory killer takes it out. After that, if the service still wants to run, then a new process will be created for it to be restarted in.
The upshot is that for normal services that are running a long time, it is expected behavior that their process will get killed after a while. This doesn't need to stop the service; a service that wants to continue running will do so, it will just need to be instantiated in a new process.
Of course as long as the user is interacting with an activity in your process, the process won't be killed, since this pulls it to the foreground category regardless of what is going on with any services in it.
Processes are killed by the low memory killer, not Applications. So unless you do extra work to get your Service running in a different process, then your Activities are killed along with your Service.
The low memory killer doesn't try to destroy any objects in your process, although the activity manager may call onDestroy on Activity objects that are no longer needed. But that happens as part of the regular activity lifecycle, not due to low memory conditions.
(By the way, I'm unclear whether you mean "application" in general, or your object that extends Application, or whether you mean your Activities that show the UI.)
An application is something that has a user interface and if you have included a service along with it, then definitely it will be killed since Applications are terminated once the cached application queue becomes full
so create Service separate from application or in other words create an other project for it :)
btw, i'm not an experienced Android developer but thats i think what i learned by watching the Android development life cycle videos by Google

Android Application class lifecyle documentation

I'm trying to find the official documentation about the Android Application class lifecycle. Apparently, for what I found on StackOverflow here and here the Application class can be killed if the system needs memory. Even this tutorial says so.
But few things irritates me a bit about this:
I can't find an official documentation telling me that yes, the Application class can be killed on low memory.
I can't find any official diagram representing the Application lifecycle neither.
I can't find any proper callback to use when the Application class is killed except onLowMemory(). Does it mean that I have to use this method to persist my data?
If the Application class is killed on low memory pressure and the app comes to foreground again, how can I know in its onCreate() that the app has been recreated after a system kill? In an Activity I would test the savedInstanceState, but as far as I know there is nothing similar in the Application class.
Thank you for your enlightenments.
I can't find an official documentation telling me that yes, the Application class can be killed on low memory.
Below are the references to where it's been stated:
Application Fundamentals
Processes and Threads
Multitasking the Android Way
I can't find any official diagram representing the Application lifecycle neither.
This is a reasonable observation... Although the following is opinion-based, my best guess is that such a diagram would contradict the Android's multitasking "philosophy" as described in the last reference provided:
"A key to how Android handles applications in this way is that processes don't shut down cleanly. When the user leaves an application, its process is kept around in the background, allowing it to continue working (for example downloading web pages) if needed, and come immediately to the foreground if the user returns to it. If a device never runs out of memory, then Android will keep all of these processes around, truly leaving all applications "running" all of the time."
I can't find any proper callback to use when the Application class is killed excepted onLowMemory(). Does it mean that I have to use this method to persist my data?
Regarding onLowMemory() whose description is quite straightforward, are we talking about a background process or foreground UI?...
If none of application Activities is in foreground and OS is low on memory, it may kill the app so that none of the Application's or the app component's (Activity, Service) callbacks will be invoked. That said, (since you're dealing with Activities) I recommend to store all persistent data as per the documentation, in onPause().
If the Application class is killed on low memory pressure and the app comes to foreground again, how can I know in its onCreate() that the app has been recreated after a system kill?
You can't recognize it in Application's onCreate().
As far as I know, you can't handle the application killed event. Here is a quote from the Application's onTerminate method:
This method is for use in emulated process environments. It will never
be called on a production Android device, where processes are removed
by simply killing them; no user code (including this callback) is
executed when doing so.
The general idea is that you shouldn't care whether the application was killed or not. If it was, the OS will restart the app next time it is needed otherwise it will be resume (and you'll use the Activity / Fragment lifecycle events to achieve this).
What data do you need to store - is it possible to store it earlier (when it is received from web service and so on) instead of waiting for the last moment?

Application Process still around after app is closed

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.

Android service killed

I have a Service running in the same process as my Application.
Sometimes the Android OS decides to kill my service (probably due to low memory).
My question is: does my Application get killed along with the Service? or how does it work exactly?
Thanks!
First be sure to read: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
The key to this is that on Android a process is just a container for code -- or specifically one or more components (activities, services, receivers, providers). By default all components in a .apk get their own, dedicated process, that they all run in together. This is almost always what you want.
When the user is directly interacting with a component of that process (that is an activity) Android will try very hard to keep that process running, and you won't see it killed except under extraordinary circumstances.
When the user is no longer directly interacting with the process, then it becomes expendable relative to other processes as described in the referenced documentation. That is, empty processes (no interesting components) will be killed before processes holding activities that the user had been using, which will be killed before processes with running services. So having a running service will tend to keep your process around at the expense of other processes.
At the same time, we need to deal well with more and more applications leaving services running, often indefinitely, and often with memory leaks. So has a service runs for an increasingly long time, Android will try less and less hard to keep its process going. Effectively this means moving it down to the background bucket until the out of memory killer takes it out. After that, if the service still wants to run, then a new process will be created for it to be restarted in.
The upshot is that for normal services that are running a long time, it is expected behavior that their process will get killed after a while. This doesn't need to stop the service; a service that wants to continue running will do so, it will just need to be instantiated in a new process.
Of course as long as the user is interacting with an activity in your process, the process won't be killed, since this pulls it to the foreground category regardless of what is going on with any services in it.
Processes are killed by the low memory killer, not Applications. So unless you do extra work to get your Service running in a different process, then your Activities are killed along with your Service.
The low memory killer doesn't try to destroy any objects in your process, although the activity manager may call onDestroy on Activity objects that are no longer needed. But that happens as part of the regular activity lifecycle, not due to low memory conditions.
(By the way, I'm unclear whether you mean "application" in general, or your object that extends Application, or whether you mean your Activities that show the UI.)
An application is something that has a user interface and if you have included a service along with it, then definitely it will be killed since Applications are terminated once the cached application queue becomes full
so create Service separate from application or in other words create an other project for it :)
btw, i'm not an experienced Android developer but thats i think what i learned by watching the Android development life cycle videos by Google

Categories

Resources