Android bindService or/and startService - android

I want to create Service using bindService method.
But when I close one Activity my Service is destroyed, and I don't want that.
I try to put service in foreground using startForeground(NOTIFICATION_ID, notification); service onCreate , but service still destroy.
Now I try with call two methods for starting Service at same time :
Intent bindIntent= new Intent(this, ServiceC.class);
startService(bindIntent);
bindService(bindIntent, onService, BIND_AUTO_CREATE);
By calling these two methods Service not destroyed. My app work fine with this method.
Can someone explain to me whether this is a good way or if it is not can you please give me idea why startForeground(NOTIFICATION_ID, notification); does not work ?
What is the best way to use bindService but at the same time I don't want the service to self destroy.

I Used the same solution and it's a legitimate one. From Service ref:
A service can be both started and have
connections bound to it. In such a
case, the system will keep the service
running as long as either it is
started or there are one or more
connections to it with the
Context.BIND_AUTO_CREATE flag. Once
neither of these situations hold, the
service's onDestroy() method is called
and the service is effectively
terminated.
startForeground() is not working because it just tries to prevent the service from being killed by the system, but its lifecycle is another thing: if nothing is more bound to that service and it wasn't started, it just stops.

If you start service with startService() it is not destroyed. Tried starting a service, which extends IntentService and have a loop in onHandleIntent(). When loop is finished, then service destroyed and it is not related with Activity finish. User can close application, but service is not being killed.
public class MyService extends IntentService
{
private static final String serviceName = "MyService ";
public MyService () {
super(serviceName);
}
#Override
public void onDestroy()
{
Log.v(serviceName, "onDestroy");
Toast.makeText(this, serviceName+" stopped", Toast.LENGTH_LONG).show();
super.onDestroy();
}
#Override
protected void onHandleIntent(Intent arg0) {
long endTime = System.currentTimeMillis() + 30*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
Log.v(serviceName, "Service loop");
wait(1000);
} catch (Exception e) {
}
}
}
}
}

Related

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.

stop IntentService from Activity

I need help with this situation:
I have activity, what starts IntentService.
Service do some job in while cycle and sleep for some time.
Main cycle of service is endless, so I need to stop it from activity again.
I must be able to end activity, start it again and stop IntentService from new "instance" of activity.
public class MyService extends IntentService {
public MyService()
{
super("MyService");
}
public MyService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("SERVICE", "start");
while(true)
{
SystemClock.sleep(1000);
Log.d("SERVICE", "tick");
}
}
#Override
public void onDestroy() {
Log.d("SERVICE", "end");
super.onDestroy();
}
...
Intent intent = new Intent(getApplicationContext(), MyService.class);
startService(intent);
I tried calling stopService(), but it's not working. Is there any solution how to do this?
Thanks in advance.
Service do some job in while cycle and sleep for some time.
IMHO, this is an inappropriate use of IntentService. Please create a regular Service, with your own background thread that you manage yourself.
Is there any solution how to do this?
Create a regular Service, with your own background thread that you manage yourself. For example, you could use a ScheduledExecutorService instead of your sleep() loop, using shutdown() or shutdownNow() in the service's onDestroy().

How to stop service itself?

I have for example some int myInt in a service and if myInt =1 I'd like to stop service itself. So service should stop automatically.
#Override
public void onCreate() {
super.onCreate();
if(myInt==1){
// need code for stopping service here
}
}
UPDATE
Apparently we cannot stop a service due to the nature of the Service life cycle. if you can check your condition also in OnStartCommand, Can you try calling stopself() there ?
UPDATE 2
For sample code : you can try running the stopSelf() on a seperate thread as in this post : how can i stop my RECEIVE_BOOT_COMPLETED service
use "this.stopSelf()":
#Override
public void onCreate() {
super.onCreate();
if(myInt==1){
this.stopSelf();
}
}
IF the service isnt kept alive by still being bound AND/OR by having been started as a STICKY (START_STICKY), this will work.

Service won't stop when stopService method is called

I currently have a Service that runs fine when I start it but when I try to stop it using the stopService method its onDestroy method doesn't get called.
Here is the code I use to try to stop the Service
stop_Scan_Button = (Button)findViewById(R.id.stopScanButton);
stop_Scan_Button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Log.d("DEBUGSERVICE", "Stop Button pressed");
Intent service = new Intent(CiceroEngine. CICERO_SERVICE);
releaseBind();
Log.d("Stop_Scan_Button", "Service: " + service.toString());
stopService(service);
Log.d("Stop_Scan_Button", "Service should stop! ");
}
});
Am I right in thinking that when stopService is used it calls the onDestroy method of the Service? When I press my stop scan button the onDestroy() method in my Service is not called.
Is there anything else I am missing that I should put in to stop the service?
EDIT: to add onServiceConnected() gets called when stopService is run instead of onServiceDisconnected(), why would that be happening?
EDIT:To add more info regards Binding
I call bindService in the onCreate() method and I then have the releaseBind() method unbind the Service.
Here is the code for that method:
public void releaseBind(){
unbindService(this);
}
So I presume that the unbinding is not my problem?
I am going to guess that your having a method call for releaseBind() means that you previously called bindService() on this service and that releaseBind() is calling unbindService(). If my guess is incorrect, please ignore this answer.
A service will shut down after all bindService() calls have had their corresponding unbindService() calls. If there are no bound clients, then the service will also need stopService() if and only if somebody called startService() on the service.
So, there are a few possibilities here:
You still have bound clients (e.g., other activities), in which case you cannot stop the service until they unbind
Since both unbindService() and stopService() are asynchronous, something might be going haywire with the timing, in which case you may get better luck if you call stopService() from your ServiceConnection's onServiceDisconnected() method
Also, bear in mind that the exact timing of the service being destroyed is up to Android and may not be immediate. So, for example, if you are relying upon onDestroy() to cause your service to stop some work that is being done, consider using another trigger for that (e.g., activity calling a stopDoingStuff() method through the service binder interface).
Are all your bindings closed?
A service can be used in two
ways. The two modes are not
entirely
separate. You can bind to a service
that was started with startService().
For example, a background music
service could be started by calling
startService() with an Intent object
that identifies the music to play.
Only later, possibly when the user
wants to exercise some control over
the player or get information about
the current song, would an activity
establish a connection to the service
by calling bindService(). In cases
like this, stopService() will not
actually stop the service until the
last binding is closed
.
hai guys sorry for the late answer but as far as i know i have successfull stop the service in this code: you may check a link here.
public void onClick(View src) {
switch (src.getId()) {
case R.id.buttonStart:
Log.d(TAG, "onClick: starting srvice");
startService(new Intent(this, MyService.class));
break;
case R.id.buttonStop:
Log.d(TAG, "onClick: stopping srvice");
stopService(new Intent(this, MyService.class));
break;
}
}
and in services class:
public class MyService extends Service {
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}

How to stop service by itself?

I start a service in an activity then I want the service to stop itself after a while.
I called stopSelf() in the service but it doesn't work.
How to make the service stop itself?
By saying "doesn't work", I guess you mean that the onDestroy()-method of the service is not invoked.
I had the same problem, because I bound some ServiceConnection to the Service itself using the flag BIND_AUTO_CREATE.
This causes the service to be kept alive until every connection is unbound.
Once I change to use no flag (zero), I had no problem killing the service by itself (stopSelf()).
Example code:
final Context appContext = context.getApplicationContext();
final Intent intent = new Intent(appContext, MusicService.class);
appContext.startService(intent);
ServiceConnection connection = new ServiceConnection() {
// ...
};
appContext.bindService(intent, connection, 0);
Killing the service (not process):
this.stopSelf();
Hope that helped.
By calling stopSelf(), the service stops.
Please make sure that no thread is running in the background which makes you feel that the service hasn't stopped.
Add print statements within your thread.
Hope this helps.
since you didnt publish your code, i cant know exactly what you are doing, but you must declare WHAT you are stopping:
this.stopSelf();
as in:
public class BatchUploadGpsData extends Service {
#Override
public void onCreate() {
Log.d("testingStopSelf", "here i am, rockin like a hurricane. onCreate service");
this.stopSelf();
}
If by "doesn't work" you mean the process doesn't get killed, then that's how android works. The System.exit(0) or Process.killProcess(Process.myPid()) will kill your process. But that's not the Android way of doing things.
HTH
stopForeground(true);
stopSelf();
To let your service to stop itself.. create a BroadcastReceiver class.. In your service call your receiver like this..
In service
sendBroadcast(new Intent("MyReceiver"));
In Broadcast Receiver
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.stopService(new Intent(context,NotificationService.class));
}
}
Manifest file
<receiver
android:name="MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReceiver"/>
</intent-filter>
</receiver>
Use stopSelf() to stop a service from itself.
I know this is an old question, but in my case (floating window as service) I had to remove the view first, and then call stopSelf().
windowManager.removeView(floatingView);
stopSelf();
I just ran into the same issue. In my case, I have a singleton service manager that I use to communicate with the service. In the manager the service is started like this:
context.bindService(new Intent(context, MyService.class), serviceConnection, Context.BIND_AUTO_CREATE);
By removing Context.BIND_AUTO_CREATE as suggested by Alik Elzin, I've been able to stop the service using this.stopSelf() and to have onDestroy() called when doing so. This problem is that after that I wasn't able to restart the service from the manager using the command above.
Finally I've fixed this by using a callback from the service that tells the manager to stop the service. This way the manager is always in charge when it comes to start/stop the service and everything seems to work fine. I don't know if there are any counter indications in doing it this way.
The code is really simple. Create a callback in the service and set it in the manager like this in your connection class:
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
myService = ((MyService.LocalBinder)service).getService();
myService.setCallback(new MyService.MyServiceCallback() {
#Override
public void onStop() {
stopService();
}
});
}
public void onServiceDisconnected(ComponentName className) {
myService = null;
}
};
and stop service:
public void stopService()
{
if(mServiceConnection != null){
try {
mContext.unbindService(mServiceConnection);
} catch (Exception e) {}
}
mContext.stopService(new Intent(mContext, BleDiscoveryService.class));
}
In the service, simply call myCallback.onStop() when you need to stop it.
Another dirty hack not mentioned here is to throw an exception like NPE. One day I needed to stop InputMethodService and this hack was useful.
if you use separate Thread in your service, after stopping service by calling stopSelf() or stopService() the Thread keeps running. if u want to stop Thread u should call Thread.interrupted() in the Thread(it might cause an Exception if Thread is already sleeping)

Categories

Resources