IntentService will be killed after I stop my application - android

I am referring to android design considerations: AsyncTask vs Service (IntentService?)
According to the discussion, AsyncTask does not suit, because it is tightly "bound" to your Activity
So, I launch a Thread (I assume AsyncTask and Thread belong to same category), have an infinity running loop in it and did the following testing.
I quit my application, by keeping pressing on back soft key, till I saw home screen. Thread is still running.
I kill my application, by going to Manage apps -> App -> Force stop. Thread is stopped.
So, I expect after I change from Thread to Service, my Service will keep alive even after I quit or kill my app.
Intent intent = new Intent(this, SyncWithCloudService.class);
startService(intent);
public class SyncWithCloudService extends IntentService {
public SyncWithCloudService() {
super("SyncWithCloudService");
}
#Override
protected void onHandleIntent(Intent intent) {
int i = 0;
while (true) {
Log.i("CHEOK", "Service i is " + (i++));
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Log.i("CHEOK", "", ex);
}
}
}
}
// Doesn't matter whether I use "android:process" or not.
<service
android:name="com.xxx.xml.SyncWithCloudService"
android:process=".my_process" >
</service>
However, my finding is that,
I quit my application, by keeping pressing on back soft key, till I saw home screen. Service is still running.
I kill my application, by going to Manage apps -> App -> Force stop. Service is stopped.
It seems that the behaviour of Service and Thread are the same. So, why I should use Service instead of Thread? Is there anything I had missed out? I thought my Service suppose to keep running, even after I kill my app?

Nope. Service will stop running when you kill your application. When you kill your application all components of it are killed (activities, services, etc.).
In general the behaviour of Thread and Service are similar. However, If you start a Thread from an Activity and then shutdown the activity (ie: quit your application), eventually Android will notice that your process has no active components in it (since Android doesn't recognize your Thread as an active component) and it will just kill your process, thereby killing the thread.
However, if you have a Service running, then Android will notice that you have a service running and not kill it so readily. However, it is still possible that Android will kill your service process if it isn't "in use".

Actually there are different kinds of services you can implement. Use a Service instead of IntentService. There you need to look at START_STICKY , START_NOT_STICKY and START_REDELIVER_INTENT you can keep your service running in background even if your activity dies. Android services

You are using startService(). The Service will run until it's code is done, or until Android decides it should be killed. Look up on bound services. On your Activity.onDestroy() you should call unbindService().

In your IntentService you can override onStartCommand() returning START_REDELIVER_INTENT
Then if killed, your service will be restarted automatically by the system after some time with the same Intent.
Be sure to call the super implementation on onStartCommand() like this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent,flags,startId);
return START_REDELIVER_INTENT;
}

You can invoke setIntentRedelivery(true) in the constructor of the IntentService

Related

Service restarted on Application Close - START_STICKY

I have an app that runs as a web server. The app has a service that is START_STICKY I want this service to run the web server all the time (option is given to user in a notification to stop it).
Problem is that the server is restarted (loosing settings etc) when i swipe my app closed. It stays there fine but logcat shows that it is restarting.
I can re- open my app and bind to the new service, this works fine. Although swipe closing again has the same effect.
I need this to NOT restart.
Standard service code
private WebServerService mService;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder binder) {
WebServerService.MyBinder b = (WebServerService.MyBinder) binder;
mService = b.getService();
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};
public serviceStart() {
mIntent = new Intent(mContext.getApplicationContext(), WebServerService.class);
mContext.startService(mIntent);
mContext.bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE);
}
Service on start
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, START_STICKY, startId);
Log.d("SERVICE","Started");
return START_STICKY;
}
Short answer: you can't. Every Android app can be killed by the system or by the user when the system claims memory or the user swipes out the app from the recent apps list. This is an Android design and all apps must adhere to it. The only (small) improvement you can have is setting the service as a Foreground service:
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. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Use startForeground()
The drawback is that you'll have to provide a notification.
Like Mimmo said: You can't. The system can indeed kill apps/services if low on memory. Also users can do this. Either with the force close button in app settings or swiping the app. Swipe to close is like the force stop. The app/service DOES NOT RESTART when closing an app like this. That is just how the system works. Try it yourself, download advance task killer and kill Facebook for example. If you restart advance task killer a few seconds later, you will see Facebook is running again. Now open Facebook and use the swipe function to kill it. Now start the task killer again. You will see Facebook is not running anymore. Again, that is how the system works.
Setting the service as a Foreground service is not going to help either.
Will the tag android:process="anyname" on your manifest be useful? It makes the service run on a different process of your app.
http://developer.android.com/guide/topics/manifest/service-element.html#proc
As appointed by others it still can be terminated by the system if running low on memory but it won't terminate by closing your app. Hope it helps.

android - service stops when activity is destroyed

when I open the activity of my project I call the startService(Intent intent) method to start a new Service.
When the activity is destroyed the service shouldn't be killed (because I didn't use the bindService() method), but the fact is that when I close my activity the service is killed and after a second the system creates a new Service (I verified that, the system calls again the onCreate() method of my service). What do I have to do to keep only one service ? Thank you
To have a service running independently of your application's main process and to be sure that Android does not kill it while it's doing something, there are two things you should do/try.
Run your service in a separate process. You can achieve this by adding the following attribute to your service declaration in the manifest:
android:process=":somenamehere"
When your service is running and you do not want it to be killed by the OS, you have to use the startForeground(int id, Notification notification) method. When the service finishes whatever is doing and can be killed by the OS, call stopForeground(boolean removeNotification). "startForeground" requires a notification as argument because every foreground service must display a notification so the user realizes about it
I hope this helps you.
I mean I hold the home button and then kill my activity from the list of app open
That does not "close" an activity. That terminates your process. The user is welcome to terminate your process whenever the user wants, whether via this means or through third-party task manager apps. There is nothing you can do about this -- you cannot stop the user from terminating your process. Since your process will stop for other reasons as well (e.g., sheer old age), you have plenty of reasons to handle this case.
Edit: Please refer to CommonsWare's answer
Old answer: You should override public int onStartCommand(Intent intent, int flags, int startId) method and return START_STICKY value as the mode of your service.
this will keeps your service working when the activity is destroyed or even when you exit your app unless you call stopService(Intent) explicitly

Start service when the application exit (or is killed)

I would like to start my foreground service when my application is closed.
I tryed OnStop() but it's not a good idea for me because it can trigger multiple times and i which it to run only one instance.
I tryed OnDestroy() but it's simply doesn't trigger since i'm only using one activity in my whole app and most of time it is being kill with the SWIPE.
Is there a way i can detect when my application being kill or close ?
Thanks!
Only one instance of the service will run no matter how many times you start it. Each time a client starts the service the onStartCommand method fires. return Service.START_STICKY; to have your service stay running in the back ground after your app exits. But be warned if things get busy and the phone needs memory your service will be killed and you'll have to restart it like #Onur suggests with a conservative periodic AlarmManager intent.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// the service is started so after all clients are unbound it stays
// running
return Service.START_STICKY;
}
You can add your services description in manifest.xml stopWithTask="false" and in your sevice override the onTaskRemoved (Intent rootIntent) to know when activity that started the service is stopped for API level 14 and later.
Or you can set an alarm for some periods to check if your application is still running using AlarmManager. You should be careful with this tho, because it might consume battery based on the period you choose.

How can we restart service?

I am developing android application which has background running Service.
When I swap out app from the "Recent app List", it will cause the application to shutdown and stop the service. (The following method has the code for the same.)
#Override
public void onTaskRemoved(Intent rootIntent)
{
//code to be executed
//Stop service
super.onTaskRemoved(rootIntent);
}
Service start up code is in Application class(onCreate()), it will never be executed if app gets resume.
Positive Scenario
1) If I relaunch app after successful execution of service, new instance of app will be
created and service will also start.
Negative Scenario
1) Because there is some code in the above method which is responsible to stop the thread and the service, it causes the app to take some time to stop the service (after swapping from the recent apps).
During this time if I relaunch the application, the application resumes instead off getting recreated.
Now, the service which was running, will stop.
So,in this type situation I have application but without background service.
How can I handle this situation?
1) Application shouldn't be re-launch until service's task is completed.
2) Start service from launcher activity.
Thanks in advance.
in onStartCommand() of Service class , You have to set return as "START_STICKY" that ensure restart service which is terminated by android platform(if app breaks).
You can check the status of the service in OnResume and restart from there using Intent
#Override
protected void onResume()
{
/* This will be called when starting the UI and resume from background
* If the service is not running, then start the service and bind to the service.
* If the service is already running, then just bind with the service. The status
* of the service is determined by the #DetermineServiceStatus function.
*/
}
You have almost no control over service' s lifetime. Background services are prone to be killed by Android, whenever system needs more resources.
The best way to design a background service is return a START_STICKY from your onStartCommand() (which you already did) to ensure that when enough resources become available, your service automatically be restarted, and the job that you perform within the background service should be implemented so that even if it is interrupted, it should succesfully continue its task when restarted by Android OS.

How to restart Service after Force Stop of app

Here is my Service
public class SService extends Service {
public void onCreate() {
super.onCreate();
someTask();
}
public int onStartCommand(Intent intent, int flags, int startId) {
someTask();
return START_STICKY;
}
public IBinder onBind(Intent intent) {
return null;
}
After force stop of app (Settings->Application->Force Stop App) my Service doesn't run. How to solve it?
As per the Android document
Starting from Android 3.1, the system's package manager keeps track of applications that
are in a stopped state and provides a means of controlling their launch from background
processes and other applications.
Note that an application's stopped state is not the same as an Activity's stopped
state. The system manages those two stopped states separately.
Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It
does this to prevent broadcasts from background services from inadvertently or unnecessarily
launching components of stoppped applications. A background service or application can
override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents
that should be allowed to activate stopped applications.
On Force stop of app, Android just kill the process ID. No warnings, callbacks are given to service/activities. As per the Android document, When the app is killed there are chances that it calls onPause().
When I tried in my app, even onPause() was not called.
I think the only way is use to that intent flag and send it from another app as suggested by Chris.
Are you sure that the service isn't restarting? The START_STICKY you put in the return should do the trick some time. It takes some time till the system restart it, you can put a log and wait to make sure it's getting restarted.

Categories

Resources