I have a service [IntentService] which runs a 'timer task' scheduled to run after every 5 minutes. I start the service when my application is installed.
Now i want to stop my service [service runs a 'timer task'], but when i use stopService() method i am unable to stop my service. I tried to put a log in the onDestroy() method of my service but stopService() does not reaches there.
Also, since stopService() returns boolean i logged its output, it is returning false.
How should i stop it??
I have a service [IntentService] which runs a 'timer task' scheduled to run after every 5 minutes.
Please do not do this. Users hate developers who do this and will force-stop your application using task killers or the Settings app. Please use AlarmManager, so you can take up less RAM and be more friendly to the user.
I start the service when my application is installed.
This is not supported. In particular, as of Android 3.1, this is impossible, even by the undocumented hack you might be using.
Now i want to stop my service [service runs a 'timer task'], but when i use stopService() method i am unable to stop my service.
Most likely, your service is already stopped. IntentService stops as soon as onHandleIntent() returns. TimerTask forks a thread to maintain its timer -- if you are creating this TimerTask in onHandleIntent(), you are leaking this thread. You have no way of ever stopping this thread. It will randomly go away once Android elects to terminate your process.
If, on the other hand, you get rid of the TimerTask and use AlarmManager, you can do your real periodic work in the IntentService's onHandleIntent() method.
Related
My IntentService checks the user's location. I need to keep it alive while the phone is turned off. In this Service I have an infinite while loop. The OS will shut it down after 8 minutes.
What other ways can I do this instead of the AlarmManager?
IntentService is supposed to be executed once. When job is done, it terminates. You may try using ordinary Service and do all work on background thread. But, system can stop this service anyway if it is low on resources. To prevent that, you can use .setForeground() method in Service and Service will not be stopped by system. But, there will be icon in notification tray.
I have an alarm that obviously calls a receiver and in the receiver it have to do some tasks and it may take some time to be done. But i heard that the onReceive() method is killed after some seconds.
I made a debug on my code and "stopped" inside the receiver and suddenly the debug stops, it happens because the onReceive() was killed?
So, what should i do?
But i heard that the onReceive() method is killed after some seconds
Correct. onReceive() is called on the main application thread. You want to get off of that thread as soon as possible. If your UI happens to be in the foreground when the broadcast is received, your UI will be frozen. Even if your UI is not in the foreground, you cannot take very long on that thread without your work being terminated.
So, what should i do?
Delegate the work to an IntentService, where you start that service in onReceive(). If the work may take 15+ seconds, I would recommend using WakefulBroadcastReceiver, so that you can ensure the device will stay awake long enough for your work to complete. But even then, "some time to be done" should be measured in seconds, maybe minutes.
How is it that an IntentService stops automatically, while a normal Service needs a stopService() call to stop it? How does this work internally?
IntentService calls stopSelf() when no more work (Intents) are in the queue to be processed. Just check IntentService.java source on a site like androidxref.com to see it:
http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/app/IntentService.java
To be more precise (check line 66 on the provided link): it doesn't actually test the queue, but calls stopSelf(int) every time. stopSelf() version that takes a startid(int) as parameter actually checks if the there are no newer start commands received by the service that still have to be handled. Because the IntentService only has one worker thread that processes intents sequentially, this test is the same as testing if the "queue is empty".
A service is a component which runs in the background, without direct interaction with the user. The Android platform provides and runs predefined system services and every Android application can use them, given the right permissions. and you can stop with following way.
Boolean stop1month = context.stopService(new Intent(context,Service.class));
or
stopSelf()
in service class for mor information see
I am working on an application which needs to do a WiFi scan every 5-6 seconds. WiFiScanner class is implemented as a service and called from the main Activity. In order to repeat tasks every few seconds, I have used Handler with postDelayed with an interval of 5000 msecs. After installing on the device the application runs fine first time. Stopping the WiFi scan process, closing and immediately reopening the application causes it to crash. I suppose its because I haven't stopped the Handler explicitly in the main activity by calling removecallbacks on the runnable, instead clicking stop would simply stop the service. Here's what logcat throws on the error.
06-14 12:30:58.181: ERROR/AndroidRuntime(23534): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.SCAN_RESULTS } in com.test.example.WiFiScanner$1#2b0a3880
I was looking through stackoverflow and found suggestions to use an AlarmManager instead. But wouldn't this require me to implement a BroadcastReciever class for the purpose as it says here? Is there any other alternative to Handler to doing repetitive tasks in a service invoked from the Main Activity?
well you can just bind the service instead of starting it. that means it's a local service which will get stopped when there arent any more activities bound to it. but be carefull because the service runs in the ui thread so move things in a background thread. what i have commonly used in situations like this is a handler that postDelayed a runnable executing an async task where you can do whatever you want to do and then rescheduling it so it runs in some time period. also remove the callbacks when the service is destroyed and start it sticky so that if it is killed it restarts and you can also remove the callbacks on start.
As an alternative you can use an intent service or a simple service with alarms that is started by the alarm on specific time periods, that calls selfStop after it has completed a scan. but if you are running frequent checks then this creates an overhead because the service needs to be created over and over again (so better keep it running then).
there is also the timerTask class but i simply find this 2 solutions better. the timer class introduces a new thread
see: Timer
And This for an implementation
and here is someone that tried to do the same thing as you are:
Timer task and answers
I have an Android Service that is started by my application and does some things in a threadPool using Executors.newCachedThreadPool()
Once it has finished doing it's work I would like the service to stopSelf(), how can I get the service to determine when it is no longer needed (ie, there are no more Threads executing) so that it can shut itself down automatically?
Do it the other way: the last Runnable should shut the Service upon completion.