Should AsyncTask.cancel(true) work?

by Nathan » Wed, 21 Apr 2010 04:43:04 GMT


Sponsored Links
 Cause it doesn't.

I have a service running an Asynctask to do some work.

I bind to it from an activity and call a cancel method. The service,
in turn, calls AsyncTask.cancel(true);

AyncTask.cancel returns true. Nonetheless, the thread is still running
happily and still doing the things in doInBackGround, sending
notifications along the way.

There is no sign that it attempted to kill the thread.

I am not using NDK calls or anything that I think should stop if from
taking down the thread.

What am I doing wrong? Or is this a known issue?

Nathan

public final boolean cancel (boolean mayInterruptIfRunning)

Since: API Level 3
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Parameters
mayInterruptIfRunning   true if the thread executing this task should be
interrupted; otherwise, in-progress tasks are allowed to complete.
Returns
false if the task could not be cancelled, typically because it has
already completed normally; true otherwise

--



Should AsyncTask.cancel(true) work?

by Nathan » Wed, 21 Apr 2010 05:04:56 GMT


 Because it isn't.

AsynTask.cancel(true) is called from a service on its AsyncTask

It returns true.

After the call, AsyncTask.iscancelled() is true.

Nonetheless, the thread is still running happily and performing the
tasks in doinBackground as if nothing had happened. I can see this all
in the debugger.

Any ideas? Is this a known issue?

I see no evidence that this is working according to its documentation,
below.

Nathan

public final boolean cancel (boolean mayInterruptIfRunning)

Since: API Level 3
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Parameters
mayInterruptIfRunning   true if the thread executing this task should be
interrupted; otherwise, in-progress tasks are allowed to complete.
Returns
false if the task could not be cancelled, typically because it has
already completed normally; true otherwise

--


Sponsored Links


Should AsyncTask.cancel(true) work?

by Dianne Hackborn » Wed, 21 Apr 2010 05:12:27 GMT


 Killing threads is horribly bad and not something anyone should do.  You
need to check in your task if it has been canceled, and return if so.




>



Should AsyncTask.cancel(true) work?

by Nathan » Wed, 21 Apr 2010 06:16:52 GMT


 


I don't necessarily disagree. But that is what the documentation says
it does. So someone who wrote the documentation thought killing
threads was fine and the person who implemented it thought differently
and ignored the parameter? They should probably talk.

When Android kills the service, which it can do at any time without
warning, does it kill the Async threads?  I'm assuming so. So it
sounds like I do have to handle thread death whether I initiate it or
not.

Nathan

--



Should AsyncTask.cancel(true) work?

by Mark Murphy » Wed, 21 Apr 2010 06:25:04 GMT


 




I am fairly certain the person who wrote the documentation and who wrote
the class is the same person, and I'm not aware that he suffers from
multiple personality disorder. :-)

The documentation, as you quoted earlier, says:

"If the task has already started, then the mayInterruptIfRunning
parameter determines whether the thread executing this task should be
interrupted in an attempt to stop the task."

That does not imply, however, that the thread is interruptible. That's a
Java thing, not an AsyncTask thing.

I'm with Ms. Hackborn on this one -- I avoid designs that require Java
threads to be stopped.


If by "kills the service" you mean "destroys the service", then no, I'm
reasonably certain the threads are not killed. The AsyncTask will run to
completion regardless of the status of the component that started is.
Leastways, I'm rather sure this is what happens with activities, and I'm
not aware of any differences with respect to services in this regard.
AsyncTask maintains a thread pool, so even when the task is complete,
the thread does not necessarily terminate.

If by "kills the service" you mean "terminates the process", then yes,
the thread will go away when the process goes away.

-- 
Mark Murphy (a Commons Guy)
 http://commonsware.com  |  http://twitter.com/commonsguy 

Android Training...At Your Office:  http://commonsware.com/training 

--



Should AsyncTask.cancel(true) work?

by abisai rangel » Wed, 21 Apr 2010 06:50:56 GMT


 New HP Slate Photos here ----> Website with
photos< http://bizoppoffer.com/x/0/1320/6428/> ;








>



Should AsyncTask.cancel(true) work?

by Nathan » Wed, 21 Apr 2010 07:11:05 GMT


 


OK, that's what I needed to check on. The task is doing IO so it
should get interrupted eventually, but I could be catching it as an
IOException and continuing.

At any rate, the graceful cancellation works.



OK, now I'm worried. I see a possible runaway task here with no way to
cancel.

I should of course call AsyncTask.cancel() in onDestroy()

But Ms. Hackborn has stated in previous threads that onDestroy() won't
necessarily be called when a service is destroyed.

If the process is alway terminated when a service is destroyed without
warning, then I won't worry about the runaway task.

Nathan

--



Should AsyncTask.cancel(true) work?

by Dianne Hackborn » Wed, 21 Apr 2010 07:20:55 GMT


 



onDestroy() won't be called only in the case where your entirely process is
killed to free up memory.

-- 
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails.  All such
questions should be posted on public forums, where I and others can see and
answer them.

--



Should AsyncTask.cancel(true) work?

by Nathan » Wed, 21 Apr 2010 07:28:25 GMT


 


OK, no worry about runaway threads then. But I will be watching the
memory.

Nathan

--



Other Threads

1. Froyo On Beagle

Hi All,
                 Anyone ported the Froyo on Beagle Board.
Kindly guide me.

with regards,
saminath

-- 

2. GridView Problem

€ndroid

[IMG]http://i642.photobucket.com/albums/uu144/
aloha1003/2010-08-06_131638.png[/IMG]

http://i642.photobucket.com/albums/uu144/aloha1003/2010-08-06_131638.png
ridView


gc_mob.java
[code]package gc.mob;

import android.app.Activity;
import android.os.Bundle;

import android.view.View;
import android.widget.GridView;

import android.widget.AdapterView.*;
import android.widget.Toast;
import android.widget.*;

public class gc_mob extends Activity {
    /** Called when the activity is first created. */
        private GridView gv;


        private String[] items  = {
                        "RSS" , "Album" , "Blog"
        };
        private int[] icons     ={
                        R.drawable.sample_0,
                        R.drawable.sample_1,
                        R.drawable.sample_2
        };
        @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

      gv        =       (GridView) findViewById(R.id.gridview);
        GC_MainGridView gc_adapter      =       new
GC_MainGridView(this,items,icons);
        gv.setAdapter(gc_adapter);





        gv.setOnItemClickListener(new OnItemClickListener(){
                public void onItemClick(AdapterView<?> parent,View v,int
position , long id){
                        Toast.makeText(gc_mob.this, "" + position,
Toast.LENGTH_SHORT).show();
                }
        });

    }

}[/code]
main.xml
[code]<GridView xmlns:android="http://schemas.android.com/apk/res/
android"
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:columnWidth="90dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"

<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/icon"></
ImageView>


<TextView android:text="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/text"></
TextView>
</GridView>[/code]

GC_MainGridView.java
[code]package gc.mob;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.content.*;
import android.widget.*;
public class GC_MainGridView extends BaseAdapter {

        private Context _con;
        private String[]        _items;
        private int[]   _icons;
        public GC_MainGridView(Context con, String[] items, int[] icons)
        {
                _con    =       con;
                _items  =       items;
                _icons  =       icons;
        }
        @Override
        public int getCount() {
                // TODO Auto-generated method stub
                return _icons.length;
        }

        @Override
        public Object getItem(int position) {
                // TODO Auto-generated method stub
                return _icons[position];
        }

        @Override
        public long getItemId(int position) {
                // TODO Auto-generated method stub
                return position;
        }

        @Override
        public View getView(int position, View v, ViewGroup parent) {
                // TODO Auto-generated method stub
                ImageView imageView;

        if (v == null) {  // if it's not recycled, initialize some
attributes
            imageView = new ImageView(_con);
                ImageView iv = (ImageView) imageView.findViewById(R.id.icon);
                TextView tv     =       (TextView) 
imageView.findViewById(R.id.text);

            iv.setImageResource(_icons[position]);
                tv.setText(_items[position]);
        }else {
            imageView = (ImageView) v;
        }
                return imageView;
        }

}
[/code]


 gc_android(:gc.mob)€

ebug
Thread [<1> main] (Suspended (exception RuntimeException))
        ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord,
Intent) line: 2663
        ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord,
Intent) line: 2679
        ActivityThread.access$2300(ActivityThread, ActivityThread
$ActivityRecord, Intent) line: 125
        ActivityThread$H.handleMessage(Message) line: 2033
        ActivityThread$H(Handler).dispatchMessage(Message) line: 99
        Looper.loop() line: 123
        ActivityThread.main(String[]) line: 4627
        Method.invokeNative(Object, Object[], Class, Class[], Class, int,
boolean) line: not available [native method]
        Method.invoke(Object, Object...) line: 521
        ZygoteInit$MethodAndArgsCaller.run() line: 868
        ZygoteInit.main(String[]) line: 626
        NativeStart.main(String[]) line: not available [native method]

Source not found.



-- 

3. NFS mount issue in Android

4. unable to play rtsp stream in htc hero mobile

5. Why died Internet (Chrome) on Android 2.1 (HTC Desire)

6. Video Buffering Problems

7. View on Image