How to force an IntentService to stop immediately with a cancel button from an Activity?
Stopping a thread or a process immediately is often a dirty thing. However, it should be fine if your service is stateless.
Declare the service as a separate process in the manifest:
<service
android:process=":service"
...
And when you want to stop its execution, just kill that process:
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
Iterator<RunningAppProcessInfo> iter = runningAppProcesses.iterator();
while(iter.hasNext()){
RunningAppProcessInfo next = iter.next();
String pricessName = getPackageName() + ":service";
if(next.processName.equals(pricessName)){
Process.killProcess(next.pid);
break;
}
}
Stopping an IntentService from an activity
Are you passing a new Intent
into stopService(Intent)
or the original one used in startService(Intent)
. Passing the original Intent should stop the service.
Failing that you could use a Handler
to pass the service a Message
. Have the IntentService
implement the Handler.Callback
interface and create a new Handler(Handler.Callback)
in your Activity
, passing your IntentService
as callback. Then implement the onHandleMessage()
in your IntentService to call stopSelf()
and have your Activity
pass a message to it when you want it to stop.
Proper way to stop IntentService
My problem is that I don't know how/when to stop the service.
IntentService
automatically stops itself when onHandleIntent()
ends, if no more commands had been sent to it while onHandleIntent()
was running. Hence, you do not manually stop an IntentService
yourself.
When I call stopself() in onHandleIntent(Intent ..) all Intents which are waiting in the IntentService queue are removed.
Which is why you do not do that.
But I don't want to stop the service from an activity because I want to complete upload proccess even if my application is not running.
Then you let the IntentService
stop itself.
How to stop Intent Service in middle of my program?
You cant stop your IntentService
that way. IntentService
is stopped itself automatically.
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
You can define a boolean isStop
value in your IntentService
and change the value when stop service
button is clicked. You have to check the boolean in the for
loop like:
// when click button
YourIntentService.isStop = true;
// in for loop
for (int i=0; i<=100; i++){
if(isStop) break;
Intent intent1 = new Intent();
intent1.setAction("Start");
intent1.putExtra("count",i);
sendBroadcast(intent1);
Log.v("abc",""+i);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
For best pratice, you should use LocalBroadCastReceiver
instead of static boolean value.
Force stop loop function in IntentService
create a variable in the class.
Create a setter to set the variable true.
In you rcounter routine, check for the variable being set.
private val cancelCounter = false
public fun setToCancel() {
cancelCounter = true
}
/*Stuff*/
fun counter(bc: Intent){
for (i in 1..100){
if (cancelCounter) {
cancelCounter = false
break
}
bc.putExtra(PARAM_OUT_MSG, i.toString())
Thread.sleep(1000)
d("number", i.toString())
sendBroadcast(bc)
}
}
You may not have direct access to the object from main - if not then you should create this class with a singleton pattern ;)
I don't code in kotlin enough to now the "right way" to do it, but some links to the right way:
https://blog.mindorks.com/how-to-create-a-singleton-class-in-kotlin
https://medium.com/swlh/singleton-class-in-kotlin-c3398e7fd76b
Both of these links have some information about why they make the decisions they make in the structure pattern, and some of how the code behind for the implementations works too ;)
Manually ending the IntentService worker thread
As sonykuba said, finishing the onHandleIntent method stops the Service. So you could do something like this:
public void onHandleIntent {
try {
// ... your code here
} catch(YourException e) {
// do something with the exception
return; // this prevents the rest of the method from execution
// and thereby stops the service
}
// rest of your code
}
Related Topics
How to Programmatically Scroll Android Webview
Android Support Library Error After Updating to 23.3.0
My Android Camera Uri Is Returning a Null Value, But the Samsung Fix Is in Place, Help
Gradle Flavors for Android with Custom Source Sets - What Should the Gradle Files Look Like
How to Detect If Android Device Is Paired with Android Wear Watch
How to Pass Values Between Activities on Android
How to Create Datepicker and Timepicker Dialogs in Fragment Class
Upload an Image Using Google Volley
How to Create Ripple Effect for Pre-Lollipop
How to Limit Fling in Android Gallery to Just One Item Per Fling