onDestroy being called but service not ending - android

I'm following the book 'Beginning Android 4 Development', and I'm controlling a service using the following functions from buttons:
public void startService(View view) {
startService(new Intent(getBaseContext(), QOLService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), QOLService.class));
}
QOLService.java includes
public class QOLService extends Service {
int counter = 0;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Keep running service until stopped, so return sticky
Timer timer=new Timer();
TimerTask tt =new TimerTask() {
#Override
public void run() {
Log.d("QOLService", String.valueOf(++counter));
}
};
timer.scheduleAtFixedRate(tt, 0, 1000);
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();
}
As intended, on pressing the start button I get the 'service started' toast, and in logcat I get a message incrementing every second. This continues, as intended, even when the application is closed.
When I click the stopservice button, I also get the expected 'service destroyed' message, but the timer lives on! If I close the application it still keeps going. If I click the stopservice button again, it does NOT given the service destroyed message, as if it had been successfully destroyed the first time.
Am I calling my timer inappropriately? If so, I seem to be doing it exactly as the book advises!

Am I calling my timer inappropriately?
You are never stopping the timer. Hence, it will keep running until the process is terminated. You should stop the timer in onDestroy().

I am agree with CommonsWare, You haven't stop your timer in the code. I suggest you to go this way,
public class QOLService extends Service {
int counter = 0;
Timer timer;
TimerTask tt;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Keep running service until stopped, so return sticky
timer=new Timer();
tt =new TimerTask() {
#Override
public void run() {
Log.d("QOLService", String.valueOf(++counter));
}
};
timer.scheduleAtFixedRate(tt, 0, 1000);
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();
tt.cancel();
timer.cancel();
}
}
The cancel() method will stop your Timer as well as.

It might be because the system is trying to restart your service because you are returning START_STICKY from onStartCommand. Try returning START_NOT_STICKY instead.

Related

Run a service in background continuously

Run a service in background continuously. For example, a service has to be kicked off which will display a toast message 20 seconds once even if the app is closed.
public class AppService extends IntentService {
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public AppService() {
super("AppService");
}
#Override
protected void onHandleIntent(Intent workIntent) {
Toast.makeText(getApplicationContext(), "hai", Toast.LENGTH_SHORT).show();
SystemClock.sleep(20000);
}
}
Below code works for me...
public class AppService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
Accepted answer will not work on from Android 8.0 (API level 26), see the android's background limitations here
Modification in Accepted Answer:
1: You have to invoke the service's startForeground() method within 5 seconds after starting the service. To do this, you can call startForeground() in onCreate() method of service.
public class AppService extends Service {
....
#Override
public void onCreate() {
startForeground(9999, Notification())
}
....
}
2: You must call startForegroundService() instead of startService() by checking API level from where you want to start the service.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
This code work for me..
public class ServiceClass extends Service {
public static final int notify = 300000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Log.d("service is ","Destroyed");
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d("service is ","running");
}
});
}
}
}
In your manifest, where you declare your service, add:
android:process=":processname"
This lets the service run on a separate process and thus it will not be killed with the app.
You can then chose if you want to use foreground. It will show a persistent notification, but reduces the likelihood if the service being killed.
Further, if you want to create a continuously running service, use Service, NOT IntentService. IntentService stops when it is finished doing its action.

Service doesnot stop after activity destroy

I have written a service with timer to do something periodically but when I stop service service from mainActivity if my service is in middle of their task it's continue to finish and after that stop it and the same issue when i want to close application that call OnDestroy on Main Activity service work and after finish their task don't start again.
My Question is how can Force stop service when i want to exit from my app?
this is my service code
public class MyTimerService extends Service{
private static int counter = 0;
private Timer timer = new Timer();
private int INTERVAL;
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
INTERVAL = intent.getIntExtra("time", 500);
repaet();
return START_NOT_STICKY;
}
private void repaet() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.i("Saeed", String.valueOf(++counter));
}
}, 0, INTERVAL);
}
#Override
public void onDestroy() {
Toast.makeText(this, "Stop Service", Toast.LENGTH_LONG).show();
if(timer!=null){
timer.cancel();
}
stopSelf();
super.onDestroy();
}
}
Have you tried to manually stop your service inside onDestroy() by using this stopService()?

Keep alive Service in background?

For a demo I print a Toast after Evert 10 sec. using Service class.
It works fine, I'm getting the Toast after every 10 sec if I am on the Activity when I leave the app, Service is not giving the o/p.
But I want to that toast either I'll kill the App or back press Here is code snippet :
ServiceDemo.java
public class ServiceDemo extends Activity {
private Handler myHandler = new Handler();
private Runnable drawRunnable = new Runnable() {
#Override
public void run() {
as();
myHandler.postDelayed(this, 10000);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_demo);
myHandler.postDelayed(drawRunnable, 10000);
startService(new Intent(this, MyService.class));
}
public void as(){
startService(new Intent(this, MyService.class));
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
Service.java
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "HOHO Service Created...", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
}
}
Edit 1
moveTaskToBack(true);
I put this into the onBackPressed method I Service give the o/p if I am not on the screen but When I kill the App, Service not responding
I think you need to override onStartCommand instead of onStart()
like:
public int onStartCommand(Intent intent, int flags, int startid)
{
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
i think AlarmManager is what you want.
You have to user AlarmManager, here's an example : Alarm Manager Example
Your task will be executed even if the application is terminated.
But if the application is killed by the user, the Alarm will be canceled. See this discussion How to create a persistent AlarmManager

Can not close the service when close the background

I write this code in the onDestroy() method.
#Override
public void onDestroy()
{
MessageService.this.stopSelf();
messageThread.isRunning = false;
System.exit(0);
super.onDestroy();
}
And close the service in other Activity.
stopService(new Intent(MainOptionActivity.this,MessageService.class));
I tried many code, it can not close the service when close the background. Could anyone give me some advice? Thanks.
Here is a simple code for service class
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(getApplicationContext(), "MSG onCreate SERVICE", Toast.LENGTH_LONG).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "MSG onStartCommand SERVICE", Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Toast.makeText(getApplicationContext(), "MSG STOP SERVICE", Toast.LENGTH_LONG).show();
super.onDestroy();
}
}
and here is the code for testing this service
startService(new Intent(this, MyService.class));
new Timer().schedule(new TimerTask() {
#Override
public void run() {
startService(new Intent(getApplicationContext(), MyService.class));
}
}, 5000);
new Timer().schedule(new TimerTask() {
#Override
public void run() {
stopService(new Intent(getApplicationContext(), MyService.class));
}
}, 10000);
this is working just fine. Also add this code in manifest
<service android:name=".MyService" />
Don't use System.exit(0) on Android, instead use finish (in Activity for example).
But there is no need to stop itself onDestroy method, it is actually gonna be stopped and destroyed (that's what onDestroy method is for).
You stop the execution of the method with System.exit(0); and therefore system never reaches super.onDestroy(); point and service is not destroyed.
Try just
#Override
public void onDestroy() {
messageThread.isRunning = false;
super.onDestroy();
}

Run Android services Until App Destroyed

Actually i have to perform some technique in which some particular method will be called after specified time until app destroyed.I Google it and have found services.Using services this work can be performed.I have gone through many Service tutorials so now i can work with services but can anybody tell me how to do this. Should i use services for call particular tack in the background of the activity after specified time?...Thanks....
Edit: I have used following code
public class MyService extends Service {
int count = 0;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
handler.removeCallbacks(updateTimeTask);
handler.postDelayed(updateTimeTask, 1000);
Toast.makeText(this, "Service started................",
Toast.LENGTH_SHORT).show();
}
private Runnable updateTimeTask = new Runnable() {
public void run() {
if (count == 50) {
count = 0;
Tocken_parser tocken = new Tocken_parser();
tocken.tockenParser("1");
Toast.makeText(MyService.this, "coutn===", Toast.LENGTH_SHORT)
.show();
System.out.println("Count ===============");
}
count++;
handler.postDelayed(this, 1000);
}
};
private Handler handler = new Handler();
#Override
public void onDestroy() {
super.onDestroy();
System.out
.println("Service destroyed........................................");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Its working properly but tell me one thing, how to stop services when activity destroyed.
The answer is YES. Also, the Service that spawned by Activity will be destroyed together; unless, you assign a schedule check on Alarm to wake up your dead Service.

Categories

Resources