I still don't get how the Application (not Activity) lifecycle is,
It is pretty obvius that Application's onCreate method is called when you start the GUI.
But, is it started in ANY or ALL of the following cases?
App Widget is visible
Broadcast receiver receives something
Push notification arrives to device and show message
Push notification is clicked after the app has been closed (like from Notification Center)
Service is started
And how long will the Application process will be kept alive?
Right now I have a problem that I see that the application (process) is restarted after I close/kill the app. However there is nothing implemented so to have this behavior.
But, is it started in ANY or ALL of the following cases?
Your Application instance is created as part of starting up your process.
App Widget is visible
Simply being visible has nothing to do with your app and its process. Your app and its process will get involved for populating the app widget, when it is created and when it is updated. If, for example, updatePeriodMillis is triggering updates, and when the time comes around, you do not have a process, then an Application instance is created as part of starting up the process, before the AppWidgetProvider is called with onUpdate().
Broadcast receiver receives something
If your process already existed, your Application instance already existed. If your process did not exist, then an Application instance is created as part of starting up the process, before the BroadcastReceiver is called with onReceive().
Push notification arrives to device and show message
If you mean GCM, since this comes in as a broadcast, see above.
Push notification is clicked after the app has been closed
I have no idea what you mean by this.
Service is started
If your code is starting the service, then your process was already running and you already have an Application. If some other process is starting your service, and your process is not running, then an Application is created, before the Service, as part of creating your process.
And how long will the Application process will be kept alive?
If by "Application process", you mean "process", your process will be around for somewhere between a millisecond and a millennium, roughly speaking. It will be around until Android terminates it to free up system RAM for other apps, or until something specifically gets rid of it (e.g., "task killer", force-stop in Settings).
Application onCreate() is called when the application was dead, and it was started.
For example:
You start your app when it is not running (first time running it in a session or you start it after force stopping it)
You quit every activity for a long time (it is not killed immediately!) and Android decides to close your app and you restart it
You put the app in background, load Chrome, load some stuff, then Android decides that your app should perish and murders it (process com.example.acme.helloworld has died.) and the application itself is murdered along with every static variable, and your app is recreated from scratch but your activities load from the Activity Stack and the onSaveInstanceState -bundle
Considering the push notification receiver service is most likely in a different process, I would assume that can also start your application instance from scratch.
Related
I am working on an Android application that most it logic is done in background and basically analyzing the user activities (walking, running, in_vehicle etc)..
The ui has only 2 screens for basic setup and for giving permissions.
In the Application class onCreate (not Activity) the app register to ActivityRecognition api and gets the ActivityDetected events in a broadcast receiver which process the DetectedActivity and so on.
The app has also a boot complete receiver, after device boot, the receiver onReceive invoked.. This, causing the Application class to start, onCreate is invoke, the ActivityRecognition begins as described. This works perfectly!
So actually, the process starts in boot complete and nothing stops it..
Additionally, in the Application onCreate I send a firebase analytics Event (like AppStarted)
Also, when ActivityRecognition registration done I send another event (like ActivityDetectSuccsesfullySrarted)
Now here is the thing, in firebase I see that these events are sent about 20 times a day!!
Is there explanation for this?
This means that something, kills and recreate the process? Why?
Android terminates unused processes to free up system memory.
If you want a process to run for a long time on an off-the-shelf Android device, you will need to use a foreground service. If you are working with your own custom firmware, you could take other steps to try to keep your process around.
I'm developing a player app.
For this reason, it uses a foreground service to handle the playback.
Until recently the service was bound to my activities.
This is not the case anymore.
Since then, some specific devices (mostly Pixel 1/2/3) have been killing my app 1 minute after the screen has been turned off
The service is a foreground service not bound to anything.
Why would the device kill it?
As soon as the app is excluded from the device-optimized apps list the issue is solved
I'm not providing code, because I'm just trying to understand if this situation makes sense and if so what should I do to prevent this
BTW the app is using a receiver to act on Screen_ON/OFF messages. That's how I can see in the logs that the player service onDestroy() method gets killed exactly 1 minute after the screen has been turned off
what should I do to prevent this?
The key point here to keep the service alive is as said in official documentation :
While an app is in the foreground, it can create and run both
foreground and background services freely.
so, we can conclude that keeping the work in foreground and visible to the user has very minimal chances of being killed. And to do so we need to know that how android gets the idea that this process is in foreground ?
Here are the criteria's at which a process is said to be in foreground:
It has a visible activity, whether the activity is started or
paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to
one of its services or by making use of one of its content
providers. For example, the app is in the foreground if another app
binds to its:
-IME Wallpaper service
-Notification listener
-Voice or text service
If none of those conditions is true, the app is considered to be in
the background.
If none of the above criteria is fulfilled by your app process then thats the reason of your service being killed.
You can read more on this topic here :
Foreground service being killed by Android
I am building one of those SOS apps. Whenever the device is shaken above a threshold value (detected through accelerometer), I am showing a Toast (as of now)
1) App is launched. User gives name, email, etc.. and clicks finish on last screen.
2) Service is started which keeps listening for shake.
3) It detects the shake correctly if the App is running.
4) If I close the app (the activity), the service gets killed along with it.
How do I keep the service running even if app is closed, so that it can listen to shakes from background? (That's the whole purpose of this app)
[1.I am returning START_STICKY in onStartCommand
I also tried using a BroadcasterReciever which will restart service by receiving broadcast from onTaskRemoved
I am testing on ASUS Xenfone Max, Marshmallow OS
]
You have two options:
Start your service as foreground service (with startForeground(int id, Notification notification): docs. But in this case you will have to show Notification in notification tray for as long as your service is running
Use separate process for your service adding in manifest to your process android:process=":nameofyourprocess"
Try starting a service without binding it to the activity (Simple unbound service). Return null on your onBind() function. Sticky services attach itself to a activity and has a lifetime as long as the attachment survives. You might have a constant notification related to your application when you use foreground services.
You can put a Service in foreground, in which case it will always be considered as active (and it will therefore have its own notification, so the user knows that an active Service is running). It won't be stopped until it goes back to background. That is what you want in your case, as you want your Service to stay alive as long as possible. As described in the Android Service documentation:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.
The idea is the same for Activities and Services, actually: when Android needs memory, it starts killing processes. The foreground processes (e.g. the Activity that is displayed on the screen, or foreground services) have a higher priority than the ones that are in background (say, a paused Activity), so they will be the last ones to be stopped by the system.
Using START_STICKY just tells the system that if it has to kill your Service, then you'd like it to restart it can. That doesn't say this Service is higher priority than the others.
How does the apps like Swiftkey, Locker Master manages to keep process alive even after it has been removed from back stack?
They also don't use sticky notification.
Update:-
I need to keep my process alive. But in my case service is active but process gets killed.
They all have one or more unbound background service.
To kill those services you can go into Settings -> Apps -> Running.
However the services may be restarted at any time by other apps or system by sending a system wide message (intent). In most cases it is restarted by
Time events
Boot complete
Other apps
Other intents
In the Swiftkey case, it will be started by Android OS when it needs to show a keyboard.
EDIT: you can specify that a service runs in a remote process by adding this to the service definition in AndroidManifest
android:process="process_name_here"
However there is no such thing as a service that cannot be killed and can run forever. Android OS may start killing your service if it is running low on resources or the service is running for a long period of time. To overcome this, you can make a forground running service, but it needs to show a notification. It can also be killed by task managers, like you mentioned. You should instead start focusing on how to save it's state so you are able to restart it later.
I'm using the BroadcastReceiver to receive SMS messages with my app, and then edit a database based on what the message says. The app works fine when it's open, but If I leave it on for a long period of time and it automatically closes the app will force close when it receives a message (I think the BroadcastReciever is still working, but the rest of the app has closed). IS there any way to keep the app from closing, or resuming it when it receives a text message?
Thanks
If you want the receiver to be persistent you should consider using a Service instead of a standard Activity for your application. BroadcastReceivers that exist in a standard activity are considered to be a foreground service only when processing onReceive as soon as the execution returns the Activity resumes its normal process priority and can be terminated by the system as needed.
From: BroadcastReceiver
Process Lifecycle
A process that is currently executing a BroadcastReceiver (that is, currently running the code in its onReceive(Context, Intent) method) is considered to be a foreground process and will be kept running by the system except under cases of extreme memory pressure.
Once you return from onReceive(), the BroadcastReceiver is no longer active, and its hosting process is only as important as any other application components that are running in it. This is especially important because if that process was only hosting the BroadcastReceiver (a common case for applications that the user has never or not recently interacted with), then upon returning from onReceive() the system will consider its process to be empty and aggressively kill it so that resources are available for other more important processes.
This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the containing process active for the entire time of your operation.
For more information on creating a service:
Developer Guides
For a detailed discussion about how to create services, read the Services developer guide.