I am starting a service with a click on a button :
Intent intent = new Intent(getActivity(), UploadService.class);
getActivity().startService(intent);
My apps makes it possible to launch several services.
I know that the first time, onCreate() is called, then if the services is running, onStartCommand() is called.
onStartCommand returns START_STICKY.
But I'm facing a strange behavior :
On the first click, the Service is called, onCreate() then onStartCommand()... etc.
On the second click, while the Service is still running, onStartCommand()... etc.
But when the first is finished, onDestroy() is called, while the second is still in progress... ?
How to avoid that?
Thanks
If you start the Service that is already running then onDestroy() of Service won't be called and the instance of Service already running will be brought to front but if your Service is finished/stopped explicitly then only its onDestroy() will be called.
Related
I built a class called MService extend Service in Android Studio , I started the service like this: - inside onClick associated with a button-
Intent serviceIntent = new Intent(getApplicationContext(), MService.class);
serviceIntent.putExtra("ID", "1");
startService(serviceIntent);
The Service onStartCommand method lunched and worked pretty good..
The problem is I don't know how to end the Service when a Button clicked, I tried to do this:
stopService(new Intent(getApplicationContext(), MService.class));
inside a onClick method , the onDestroy lunched, but the Service still running
How can I stop it?
inside a onClick method , the onDestroy lunched, but the Service still running
If onDestroy() of your service was called, then afterwards, the service is not running. Your code might still be running.
If you start things in a service, such as a background thread, it is your job to stop them and clean that up, typically in your onDestroy() method.
I want to call
onDestroy()
method of Service in android.
I already searched a lot on internet and many answers are like if
service force stop or somehow its onDestroy() will never call.
But I really need to know when service is stop.
My project is about music player.
So it uses service and there is an ongoing notification.
I need to find out when the service stop? and need to stop the music and remove the notification.
But it never shows any log of onDestroy().
Can anyone help me what is the alternative for it? if not onDestroy() then which method and how?
Edit:
I don't want to call onDestroy() explicitly. I want to remove notification when I remove my app from the device menu of running applications. Because when I stop my application, onDestroy() don't call and my notification remains in the status bar.
I have started my service with this code.
Intent playin = new Intent(this, MusicService.class);
startService(playin);
From within the Service class, call:
stopSelf();
From within another class, like your MainActivity for example:
Intent i = new Intent(this, ServiceName.class);
stopService(i);
Both of these will stop your service. Make sure you are returning START_NOT_STICKY so that the service doesn't start back up again.
When you want to stop your service then simply fire an intent to stop the service as shown below.
Intent intent = new Intent();
intent.setClass(getApplicationContext(), YourService.class);
stopService(intent);
This is to stop service forcefully.When you stop service in this manner it's guaranteed that onDestroy method is called by android framework.
Hope this helps to solve you issue.
I want to call onDestroy() method of Service in android.
Do not call this method directly
public void onDestroy ()
Called by the system to notify a Service that it is no longer used and
is being removed. The service should clean up any resources it holds
(threads, registered receivers, etc) at this point. Upon return, there
will be no more calls in to this Service object and it is effectively
dead. Do not call this method directly.
However you can check if the service is running or not.
I need to find out when service stop? and need to stop music and
remove notification.
Use the following way -
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
Then call it using - isMyServiceRunning(MyService.class).
Reference:
1) Service onDestroy().
2) how-to-check-if-a-service-is-running-in-android.
You should use Foreground service. In your case, I think it would be the best choice.
Foreground services show a status bar notification, so that users are actively aware that your app is performing a task in the foreground and is consuming system resources. The notification cannot be dismissed unless the service is either stopped or removed from the foreground.
To work with foreground service you first need to declare permission <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> in your manifest. It is a normal permission so doesn't requires user action.
then, you can start the service for you Activity or other component using applicationContext.startForgroundService(intent). this is to tell the system that this will be a foreground service.
You need to start the foreground service from within your service(usually in onStartCommand()) using startForeground(int, Notification) and stop the service foreground service using stopForeground(boolean)(it takes a boolean asking whether you want to remove the notification or not)
after starting foreground service, if you close your app or the service stops itself, the notification will be remove too.
Note: when you manually want to stop the service, you should call stopSelf() or stopService() as calling stopForeground() is not enough, it merely remove the notification from the status bar.
I have an android application which starts a service in the main activity with this command:
bindService(new Intent(ctx, MyService.class), _connection, Context.BIND_AUTO_CREATE);
The main activty does excatly nothing with this service (thats why I didnĀ“t provide the code for the Service connection). The idea is that the main activity handels the service lifetime!
It "stops" the service with this code after the user clicks the "close" button of my app:
if (_service != null) {
unbindService(_connection);
}
//Some cleanup here ...
System.exit(0);
I know at this point that no other activity is binded to the service cause every activity is called from the main activity and they unbind from the service at "onStop".
So the problem is that my Service wont call "onDestroy" when the user closes the app!
When I remove the "System.exit(0)" line it will close normally!
How can I make sure that the service is closed properly in this situation?
EDIT:
Ok I read this discussion: Is quitting an application frowned upon?.
Now I rebuild my activities. I have one activity that calls the service with startService, after that it binds the service. When the activity is destroyed it calls unbindService.
The service itself returns START_STICKY in onStartCommand to make it harder to kill it. It calls stopSelf when all work is done.
Now I have the problem that I get the ServiceConnectionLeaked message if the binding still exists! Whats about that? How could I prevent this?
Use finish() instead of System.exit(0)
I have a service with a content observer watching the calendar provider and there are some instances where i need to stop the service so the observer's onchange does not get called when adding an event and then restart the service when it is added.
In my activity I use stopService(new Intent(context,Service.class)); to stop the service then I start it up again later on trying to avoid the onchange call when the provider gets changed but it does not appear the service gets stopped because the onchange still gets called causing force closes in my database because my query in my service cant find the event yet.
so how can i get around this problem?
Try like this:
ComponentName service = startService(new Intent(this, BaseballWatch.class));
// Stop a service using the service name.
stopService(new Intent(this, service.getClass()));
// Stop a service explicitly.
try {
Class serviceClass = Class.forName(service.getClassName());
stopService(new Intent(this, serviceClass));
} catch (ClassNotFoundException e) {}
If you are returning START_REDELIVER_INTENT that might impact you. Here is what the docs say about it:
if this service's process is killed while it is started (after
returning from onStartCommand(Intent, int, int)), then it will be
scheduled for a restart and the last delivered Intent re-delivered to
it again via onStartCommand(Intent, int, int).
But, then again, that says "killed", so it shouldn't impact you.
Other than that, I'm not sure what the problem would be, but if you really can't get it to work and noone else gives you a better answer (which hopefully someone will), you could do registerReceiver(...) in the service, and then in your Activity do sendBroadcast(...), and in the onReceive in the services's receiver, call stopSelf(). I know it's sloppy, and not the best approach, but it's an idea for an alternate method.
If I understand it correctly,
bindService() with BIND_AUTO_CREATE will start a service and will not die until all bindings are all unbinded.
But if I bindService(BIND_AUTO_CREATE) at onCreate() and hit back button to close the
activity, the service calls onDestroy() and dies also.
I don't call unbind() at anytime.
So is that mean when the Activity got destroyed, the binding got destroyed also and the service gets destroyed also?
What if I want the service to be always running, at the same time when the activity starts
I want to bind it so that I can access the service?
If I call StartService() and then bindService() at onCreate(), it will restart the service at every launch of Activity. (Which I don't want).
So I could I start service once and then bind next time I launch the activity?
You need to use startService so that the service is not stopped when the activity that binds to it is destroyed.
startService will make sure that the service is running even if your activity is destroyed (unless it is stopped because of memory constraints). When you call startService, the onStart method is called on the service. It doesn't restart (terminate and start again) the service. So it depends on how you implement the onStart method on the Service. The Service's onCreate, however, is only called once, so you may want to initialize things there.
I found a solution!
The problem is when you close your activity and your service is not configured as a foreground service, android system will recognize it as unused and close it.
here's an example where I added a notification :
void setUpAsForeground(String text) {
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
mNotification = new Notification();
mNotification.tickerText = text;
mNotification.icon = R.drawable.muplayer;
mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
mNotification.setLatestEventInfo(getApplicationContext(), "MusicPlayer",
text, pi);
startForeground(NOTIFICATION_ID, mNotification);
}
(A foreground service is a service that's doing something the user is actively aware of (such as playing music), and must appear to the user as a notification. That's why we create the notification here)
you can do it with BroadcastReceivers. you'll find a lot on google how to use them