How to Force an Intentservice to Stop Immediately with a Cancel Button from an Activity

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



Leave a reply



Submit