Android - Background service stops when its invoker activity is destroyed - android

I have an always-running background service, started on my MainActivity. The problem is, when MainActivity is destroyed, my service gets restarted. This scenario is the only one in which the service stops, so the "always-running" thing is working well.
I would like to know why this is happening, and what I could do to prevent it.
My service is not bound to my activity, because I don't need it.
The service:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
...
public LocationService() {
}
#Override
public void onCreate() {
// Some initialization logic here
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
...
}
MainActivity:
public class MainActivity extends BaseActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Start location service in background
Intent intent = new Intent(this, LocationService.class);
startService(intent);
}
}
Thanks in advance! :D

I'm guessing because I don't have enough data. When your MainActivity is destroyed, the OS process hosting your application has no active activities in it, just your Service. Android recognizes that the process isn't hosting any live activities, so it kills the process to free resources. Since your Service returned START_STICKY, Android then schedules your Service for a restart. The Service gets reinstantiated in a new OS process.
You could run your Service in a separate OS process to test this theory. Just add
android:process=":remote"
to the manifest entry for the <service>. This may have other implications on your application, so be sure you understand that.
In any case, Android will randomly kill OS processes that host only services, even if they returned START_STICKY. There isn't any way to prevent that, especially on low-end devices with limited resources. It is Android's way of cleaning house ;-)

Related

issue : Service is destroyed on Killing the app [duplicate]

I am starting a service from my main Android activity as follows:
final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);
When I close the activity page by swiping it out from the recent apps list, the service stops running and restarts after some time. I can't use persistent services with notifications because of my app requirements. How can I make the service NOT restart or shutdown and just keep on running on app exit?
I'm in the same situation, so far I learned when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.
lastly, after all the research I've done I'm coming to realize that the best choice for a long running service is startForeground(), because it is made for that and the system actually deals with your service well.
make you service like this in your Mainifest
<service
android:name=".sys.service.youservice"
android:exported="true"
android:process=":ServiceProcess" />
then your service will run on other process named ServiceProcess
if you want make your service never die :
onStartCommand() return START_STICKY
onDestroy() -> startself
create a Deamon service
jin -> create a Native Deamon process, you can find some open-source projects on github
startForeground() , there is a way to startForeground without Notification ,google it
Services are quite complicated sometimes.
When you start a service from an activity (or your process), the service is essentially on the same process.
quoting from the developer notes
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
So, what this means is, if the user swipes the app away from the recent tasks it will delete your process(this includes all your activities etc).
Now, lets take three scenarios.
First where the service does not have a foreground notification.
In this case your process is killed along with your service.
Second where the service has a foreground notification
In this case the service is not killed and neither is the process
Third scenario
If the service does not have a foreground notification, it can still keep running if the app is closed. We can do this by making the service run in a different process.
(However, I've heard some people say that it may not work. left to you to try it out yourself)
you can create a service in a separate process by including the below attribute
in your manifest.
android:process=":yourService"
or
android:process="yourService" process name must begin with lower case.
quoting from developer notes
If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.
this is what I have gathered, if anyone is an expert, please do correct me if I'm wrong :)
This may help you. I may be mistaken but it seems to me that this is related with returning START_STICKY in your onStartCommand() method. You can avoid the service from being called again by returning START_NOT_STICKY instead.
The Main problem is in unable to start the service when app closed, android OS(In Some OS) will kill the service for Resource Optimization, If you are not able to restart the service then call a alarm manger to start the receiver like this,Here is the entire code, This code will keep alive ur service.
Manifest is,
<service
android:name=".BackgroundService"
android:description="#string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Main Activty start alarm manger in this way,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
this will call reciver and reciver is,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
And this Alaram reciver calls once when android app is opened and when app is closed.SO the service is like this,
public class BackgroundService extends Service {
private String LOG_TAG = null;
#Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
From Android O, you cant use the services for the long running background operations due to this, https://developer.android.com/about/versions/oreo/background . Jobservice will be the better option with Jobscheduler implementation.
try this, it will keep the service running in the background.
BackServices.class
public class BackServices extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
in your MainActivity onCreate drop this line of code
startService(new Intent(getBaseContext(), BackServices.class));
Now the service will stay running in background.
Using the same process for the service and the activity and START_STICKY or START_REDELIVER_INTENT in the service is the only way to be able to restart the service when the application restarts, which happens when the user closes the application for example, but also when the system decides to close it for optimisations reasons. You CAN NOT have a service that will run permanently without any interruption. This is by design, smartphones are not made to run continuous processes for long period of time. This is due to the fact that battery life is the highest priority. You need to design your service so it handles being stopped at any point.
You must add this code in your Service class so that it handles the case when your process is being killed
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
Why not use an IntentService?
IntentService opens a new Thread apart from the main Thread and works there, that way closing the app wont effect it
Be advised that IntentService runs the onHandleIntent() and when its done the service closes, see if it fits your needs.
http://developer.android.com/reference/android/app/IntentService.html
Best solution is to use the sync Adapter in android to start the service. Create a Sync Adapter and call start service their.. inside onPerformSync method. to create sync Account please refer this link https://developer.android.com/training/sync-adapters/index.html
Why SyncAdapter? Ans: Because earlier you used to start the service using your App context. so whenever your app process get killed (When u remove it from task manager or OS kill it because of lack of resources ) at that time your service will also be removed. SyncAdapter will not work in application thread.. so if u call inside it.. service will no longer be removed.. unless u write code to remove it.
<service android:name=".Service2"
android:process="#string/app_name"
android:exported="true"
android:isolatedProcess="true"
/>
Declare this in your manifest. Give a custom name to your process and make that process isolated and exported .
Running an intent service will be easier. Service in creating a thread in the application but it's still in the application.
Just override onDestroy method in your first visible activity like after splash you have home page and while redirecting from splash to home page you have already finish splash. so put on destroy in home page. and stop service in that method.

Service which listens to database changes

This probably shouldn't be too hard to make but I was wondering what would be the best practice in doing it. I plan to create something like this:
Service needs to be running all the time. It also needs to start when user boot his device.
Service is processing data from database so it needs to listen for database changes for one table.
After user makes an action to insert new row to database, service should register that and start processing data.
I am not sure how to listen for those changes and process them. I know I can start a service on boot by creating new Broadcats receiver:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
And defining it inside manifest:
<receiver android:name="MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And this is simple service:
public class MyService extends Service {
private final IBinder mBinder = new MyBinder();
private ArrayList<String> list = new ArrayList<String>();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Should check for database change here?
// fetches data from database
List<String> data = Manager.get(context).getData();
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
}
Service should be running now. How can I now implement periodic check of my database or listen for database changes? What would the recommended design or best practice to implement this process? Any idea is most welcome :)
EDIT
Some extra explanation. User who is using the app is the only one who can update database. It's a local SQLite database which is created inside a class which extends SQLiteOpenHelper. The database is updated when user fills some predefined EditText views inside Activity and clicks on a button to save data. Service needs to process each new row inside that table. Sometimes it can happen the user turns off his device or kills his app before data is processed. In that case service needs to continue processing data after user boots his device again or starts an app.
If your app is the only one that can modify the database, and only as a result of user action, then you always know exactly the moment your table has been updated. Simply initiate the processing whenever you perform an insert.
If you want that processing done in a service, use an IntentService. IntentService processes everything on a background thread so you can do operations like network requests, and it automatically stops itself when it has no more work to do.
I don't know how long this processing of yours takes, but I don't think you should be fearful of the app being killed or the device being turned off. If the user closes the app, the system will not kill it immediately; if the OS does need to kill one of your application components to regain memory, it is less likely to kill your IntentService than, say, the Activities that are no longer being used (and by then you might be done with your processing anyway, so it won't matter). But in general if the OS is not under memory pressure then it will keep app components around as long as possible so that it takes less time if the user switches back to that app.
The only things that would actually kill your app is a device with too much memory pressure or the user is using a task killer app. If that's truly a concern for you (or if your processing takes so long that you think those situations could happen), then you can consider persisting pending processing tasks to disk before you begin processing. When a task finishes, remove it from disk. Then your boot completed receiver only needs to check if there are pending tasks that didn't complete. You can build your own solution, or you can look at something like Path's JobQueue library: https://github.com/path/android-priority-jobqueue
You could make your service a Singleton and create another BroadcastReceiver just for database changes:
public class YourService extends Service{
private static YourService sInstance;
public static YourService getInstance(){ return sInstance; }
onCreate(){
sInstance = this;
...
}
public void processSomeData(YourData data){
//do the stuff you wanna do
}
}
And your new receiver could look like this
public class DBChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
YourData data;
//grab your data from the intent
YourService.getInstance().processSomeData(data);
}
}
Then just call sendBroadcast() when you update your database

Android keep BroadcastReceiver in background

I created a BroadcastReceiver and it runs only when my app shown in recent apps menu. If I remove my app from the recent apps the BroadcastReceiver will stop working.
How can I keep the BroadcastReceiver in background?
I register the BroadcastReceiver from my main activity (in OnCreate()).
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, intentFilter);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
This is not how you should register a receiver. You receiver stops working, because you construct it in onCreate, which means it will live as long as your app is alive. When the app gets destroyed, you also lose the the receiver.
If you register receiver inside an activity, you should always register it in onResume and deregister onPause, which will make it available while the activity is visible to the user. This is a use case when you want to have an active receiver while user interacts with an activity.
If you want a background receiver, you need to register it inside the AndroidManifest (with intent filter), add an IntentService and start it when you receive a broadcast in the receiver.
Here is a tutorial, you are interested in chapter 3.
If you need to be always on, start a foreground service. There is function in Service that lets you: startForeground. Then register your receiver when service is created and deregister when it's destroyed. Foreground services are quite nasty though.
Use a service with it.
Services can survive when the app dies if they have the right flag example:
public class MyService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY; //this defines this service to stay alive
}
#Override
public void onCreate() {
super.onCreate();
appStatus = APPISUP;
//This is a thread that stays alive for as long as you need
new CheckActivityStatus().execute();
//Not needed but in case you wish to lauch other apps from it
}
private class CheckActivityStatus extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
while(true) {
... //add something that breaks eventually
}
}
}
To lauch the service you have to lauch it from an activity like so:
Intent service = new Intent(getBaseContext(), MyService.class);
startService(service);
With the service the BroadcastReceiver still functions receiving whatever you want.
Note that the service sometimes stops and comes back. I haven't found out why but I'm betting on priorities of other apps that may ask the system to halt the service

Does stopService kill a Android service or does it wait untill it's idle?

I currently have a service that processes some stuff, and it is started with startService.
I was wondering, can I call `stopService immediately after I start the service and expect it to stop the service after the processing is done?
Or does Android kill the service when I call that command?
One hopes that "processes some stuff" is done in a background thread, assuming that it will take more than a couple of milliseconds.
Android is largely oblivious to such a background thread. stopService() will trigger onDestroy() of the service, and the service will go away. The thread, however, will continue to run, until it terminates on its own, or until the process is terminated.
can I call `stopService immediately after I start the service and expect it to stop the service after the processing is done?
Only if "the processing" is done on the main application thread (e.g., in the body of onStartCommand()), which, again, is not a good idea if such work will take more than a couple of milliseconds. And, if that indeed is the case, there's no good reason for having a service in the first place.
If you want to have a service that:
Has a background thread, and
Automatically shuts down when the work is complete (avoiding the need for stopService())
then use an IntentService.
Android can't kill just a single Service. All it can do is to kill the whole process and everything running within. Most apps will have just 1 process so this usually means Android kills everything or nothing. Most of the times nothing.
The lifecycle of a Service or Activity tells Android whether it may kill the process safely or not. The Processes and Threads describes the order in which processes are kill if there is demand for memory.
It is important to know that a Thread started from a Service / Activity it is not affected at all by onDestroy etc. It just keeps running. Android simply does not know about that thread and won't stop it for you.
That means if you want to do some background processing you have link the lifecycle of such threads to the lifecycle of your Activity / Service or Android may just kill the process and thus your thread.
Quick example of a Service that prints to logcat every second while running. Not based on IntentService since that's more or less intended for tasks with an end.
public class MyService extends Service {
public static void start(Context context) {
context.startService(new Intent(context, MyService.class));
}
public static void stop(Context context) {
context.stopService(new Intent(context, MyService.class));
}
private final ExecutorService mBackgroundThread = Executors.newSingleThreadExecutor();
private Future<?> mRunningTask;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// startService -> start thread.
if (mRunningTask == null) {
// prevents task from being submitted multiple times.
// actually not necessary when using a single thread executor.
mRunningTask = mBackgroundThread.submit(mRunnable);
}
return START_STICKY;
}
private Runnable mRunnable = new Runnable() {
#Override
public void run() {
while (!Thread.interrupted()) {
try {
// Do something
Log.d("Service", "I'm alive");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.d("Service", "Got interrupted", e);
Thread.currentThread().interrupt();
}
}
}
};
#Override
public void onDestroy() {
// stopService > kill thread.
mBackgroundThread.shutdownNow();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
According to the documentation:
stopService(Intent service)
Request that a given application service be stopped. If the service is
not running, nothing happens. Otherwise it is stopped. Note that calls
to startService() are not counted -- this stops the service no matter
how many times it was started.
Note that if a stopped service still has ServiceConnection objects
bound to it with the BIND_AUTO_CREATE set, it will not be destroyed
until all of these bindings are removed. See the Service documentation
for more details on a service's lifecycle.

Android Service Stops When App Is Closed

I am starting a service from my main Android activity as follows:
final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);
When I close the activity page by swiping it out from the recent apps list, the service stops running and restarts after some time. I can't use persistent services with notifications because of my app requirements. How can I make the service NOT restart or shutdown and just keep on running on app exit?
I'm in the same situation, so far I learned when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.
lastly, after all the research I've done I'm coming to realize that the best choice for a long running service is startForeground(), because it is made for that and the system actually deals with your service well.
make you service like this in your Mainifest
<service
android:name=".sys.service.youservice"
android:exported="true"
android:process=":ServiceProcess" />
then your service will run on other process named ServiceProcess
if you want make your service never die :
onStartCommand() return START_STICKY
onDestroy() -> startself
create a Deamon service
jin -> create a Native Deamon process, you can find some open-source projects on github
startForeground() , there is a way to startForeground without Notification ,google it
Services are quite complicated sometimes.
When you start a service from an activity (or your process), the service is essentially on the same process.
quoting from the developer notes
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
So, what this means is, if the user swipes the app away from the recent tasks it will delete your process(this includes all your activities etc).
Now, lets take three scenarios.
First where the service does not have a foreground notification.
In this case your process is killed along with your service.
Second where the service has a foreground notification
In this case the service is not killed and neither is the process
Third scenario
If the service does not have a foreground notification, it can still keep running if the app is closed. We can do this by making the service run in a different process.
(However, I've heard some people say that it may not work. left to you to try it out yourself)
you can create a service in a separate process by including the below attribute
in your manifest.
android:process=":yourService"
or
android:process="yourService" process name must begin with lower case.
quoting from developer notes
If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.
this is what I have gathered, if anyone is an expert, please do correct me if I'm wrong :)
This may help you. I may be mistaken but it seems to me that this is related with returning START_STICKY in your onStartCommand() method. You can avoid the service from being called again by returning START_NOT_STICKY instead.
The Main problem is in unable to start the service when app closed, android OS(In Some OS) will kill the service for Resource Optimization, If you are not able to restart the service then call a alarm manger to start the receiver like this,Here is the entire code, This code will keep alive ur service.
Manifest is,
<service
android:name=".BackgroundService"
android:description="#string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Main Activty start alarm manger in this way,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
this will call reciver and reciver is,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
And this Alaram reciver calls once when android app is opened and when app is closed.SO the service is like this,
public class BackgroundService extends Service {
private String LOG_TAG = null;
#Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
From Android O, you cant use the services for the long running background operations due to this, https://developer.android.com/about/versions/oreo/background . Jobservice will be the better option with Jobscheduler implementation.
try this, it will keep the service running in the background.
BackServices.class
public class BackServices extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
in your MainActivity onCreate drop this line of code
startService(new Intent(getBaseContext(), BackServices.class));
Now the service will stay running in background.
Using the same process for the service and the activity and START_STICKY or START_REDELIVER_INTENT in the service is the only way to be able to restart the service when the application restarts, which happens when the user closes the application for example, but also when the system decides to close it for optimisations reasons. You CAN NOT have a service that will run permanently without any interruption. This is by design, smartphones are not made to run continuous processes for long period of time. This is due to the fact that battery life is the highest priority. You need to design your service so it handles being stopped at any point.
You must add this code in your Service class so that it handles the case when your process is being killed
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
Why not use an IntentService?
IntentService opens a new Thread apart from the main Thread and works there, that way closing the app wont effect it
Be advised that IntentService runs the onHandleIntent() and when its done the service closes, see if it fits your needs.
http://developer.android.com/reference/android/app/IntentService.html
Best solution is to use the sync Adapter in android to start the service. Create a Sync Adapter and call start service their.. inside onPerformSync method. to create sync Account please refer this link https://developer.android.com/training/sync-adapters/index.html
Why SyncAdapter? Ans: Because earlier you used to start the service using your App context. so whenever your app process get killed (When u remove it from task manager or OS kill it because of lack of resources ) at that time your service will also be removed. SyncAdapter will not work in application thread.. so if u call inside it.. service will no longer be removed.. unless u write code to remove it.
<service android:name=".Service2"
android:process="#string/app_name"
android:exported="true"
android:isolatedProcess="true"
/>
Declare this in your manifest. Give a custom name to your process and make that process isolated and exported .
Running an intent service will be easier. Service in creating a thread in the application but it's still in the application.
Just override onDestroy method in your first visible activity like after splash you have home page and while redirecting from splash to home page you have already finish splash. so put on destroy in home page. and stop service in that method.

Categories

Resources