停止AsyncTask的doInBackground方法方法、AsyncTask、doInBackground

2023-09-12 00:39:22 作者:落落大方

我已经创建了一个类的AsyncTask的和我打电话从片段的任务。问题是我想停止doInBackground方法,如果该片段被破坏。要做到这一点,我创建在AsyncTask的写入类的方法和我用取消(真)的AsyncTask的对象的方法。当我打电话的片段这种方法的onDestroy()的后台进程仍在运行。 PLZ告诉我正确的方式来阻止的AsyncTask的doInBackground。

这是AsyncTask的写入类

 公共类CarDetail实现Parcelable {

私人字符串carId;
私人字符串carName;
私人字符串IMAGEURL;
私人字符串thumbUrl;
私人字符串dailyPrice;
私人字符串weeklyPrice;
私人字符串weekendPrice;
私人字符串存款;
私人字符串minimumAge;
私人串色;
私人字符串化妆;
私人字符串的位置;
私人字符串体形;
私人字符串fuelType;
私人字符串传输;
私人字符串carType;
私人字符串模式;
私人字符串描述;
私人位图图像;
私人位图thumbImage;
私人CarListAdapter carAdapter;
私人ImageLoadTask任务=新ImageLoadTask();

公共CarDetail(){
    超();
    // TODO自动生成构造函数存根
}

公共CarDetail(字符串carId,字符串carName,字符串IMAGEURL,
        字符串thumbUrl,字符串dailyPrice,字符串weeklyPrice,
        字符串weekendPrice,存款字符串,字符串minimumAge,
        串色,串做,字符串位置,字符串体形,
        字符串fuelType,字符串传送,字符串carType,弦模型,
        字符串描述){
    超();
    this.carId = carId;
    this.carName = carName;
    this.imageUrl = IMAGEURL;
    this.thumbUrl = thumbUrl;
    this.dailyPrice = dailyPrice;
    this.weeklyPrice = weeklyPrice;
    this.weekendPrice = weekendPrice;
    this.deposit =存款;
    this.minimumAge = minimumAge;
    this.color =颜色;
    this.make =做;
    this.location =位置;
    this.bodyType =体形;
    this.fuelType = fuelType;
    this.transmission =传输;
    this.carType = carType;
    this.model =模型;
    this.description =描述;

    //加载后 - 也可以设置为默认的图像
    this.image = NULL;
    this.thumbImage = NULL;
}

公共字符串getCarId(){
    返回carId;
}

公共无效setCarId(字符串carId){
    this.carId = carId;
}

公共字符串getCarName(){
    返回carName;
}

公共无效setCarName(字符串carName){
    this.carName = carName;
}

公共字符串getImageUrl(){
    返回IMAGEURL;
}

公共无效setImageUrl(字符串IMAGEURL){
    this.imageUrl = IMAGEURL;
}

公共字符串getThumbUrl(){
    返回thumbUrl;
}

公共无效setThumbUrl(字符串thumbUrl){
    this.thumbUrl = thumbUrl;
}

公共字符串getDailyPrice(){
    返回dailyPrice;
}

公共无效setDailyPrice(字符串dailyPrice){
    this.dailyPrice = dailyPrice;
}

公共字符串getWeeklyPrice(){
    返回weeklyPrice;
}

公共无效setWeeklyPrice(字符串weeklyPrice){
    this.weeklyPrice = weeklyPrice;
}

公共字符串getWeekendPrice(){
    返回weekendPrice;
}

公共无效setWeekendPrice(字符串weekendPrice){
    this.weekendPrice = weekendPrice;
}

公共字符串getDeposit(){
    返回定金;
}

公共无效setDeposit(字符串存款){
    this.deposit =存款;
}

公共字符串getMinimumAge(){
    返回minimumAge;
}

公共无效setMinimumAge(字符串minimumAge){
    this.minimumAge = minimumAge;
}

公共字符串的getColor(){
    返回的颜色;
}

公共无效setColor(串色){
    this.color =颜色;
}

公共字符串getMake(){
    返回化妆;
}

公共无效setMake(字符串化妆){
    this.make =做;
}

公共字符串的getLocation(){
    返回的位置;
}

公共无效的setLocation(字符串位置){
    this.location =位置;
}

公共字符串getBodyType(){
    返回体形;
}

公共无效setBodyType(字符串体形){
    this.bodyType =体形;
}

公共字符串getFuelType(){
    返回fuelType;
}

公共无效setFuelType(字符串fuelType){
    this.fuelType = fuelType;
}

公共字符串getTransmission(){
    返回传输;
}

公共无效setTransmission(字符串传送){
    this.transmission =传输;
}

公共字符串getCarType(){
    返回carType;
}

公共无效setCarType(字符串carType){
    this.carType = carType;
}

公共字符串getModel(){
    回归模型;
}

公共无效setModel(字符串模式){
    this.model =模型;
}

公共字符串getDescription(){
    返回描述;
}

公共无效setDescription(字符串描述){
    this.description =描述;
}

公共位图的getImage(){
    返回形象;
}

公共无效setImage(位图图像​​){
    this.image =图像;
}

公共位图getThumbImage(){
    返回thumbImage;
}

公共无效setThumbImage(位图thumbImage){
    this.thumbImage = thumbImage;
}

 公共无效的LoadImage(CarListAdapter carAdapter){
        //保留一个引用到适配器
        this.carAdapter = carAdapter;
        如果(thumbUrl =空&安培;!&安培;!thumbUrl.equals()){
            //新ImageLoadTask()执行(thumbUrl)。

            task.execute(thumbUrl);
        }
 }

    //异步任务,以避免哽咽起来UI线程
    私有类ImageLoadTask扩展的AsyncTask<字符串,字符串,位图> {

        @覆盖
        在preExecute保护无效(){
            Log.i(ImageLoadTask,导入图像...);
        }

        // PARAM [0] IMG网址
        受保护的位图doInBackground(字符串...参数){
            Log.i(ImageLoadTask,试图加载图片的URL:+参数[0]);
            尝试 {
                位图B = JsonParser.downloadBitmap(参数[0]);
                返回b;
            }赶上(例外五){
                e.printStackTrace();
                返回null;
            }
        }

        保护无效onProgressUpdate(字符串...进度){
            //没有OP
        }

        保护无效onPostExecute(位图RET){
            如果(RET!= NULL){
                Log.i(ImageLoadTask,成功加载+ carName +图像);
                图像= RET;
                如果(carAdapter!= NULL){
                    //在图像加载通知适配器
                    carAdapter.notifyDataSetChanged();
                }
            } 其他 {
                Log.e(ImageLoadTask,无法加载+ carName +图像);
            }
        }
    }


    / *下面这里的一切是实现Parcelable * /

    // 99.9%的时候,你可以忽略这个
    公众诠释describeContents(){
        返回0;
    }

    //写对象的数据传入的包
    公共无效writeToParcel(包裹出来,诠释标志){
        out.writeString(car​​Id);
        out.writeString(car​​Name);
        out.writeString(IMAGEURL);
        out.writeString(thumbUrl);
        out.writeString(da​​ilyPrice);
        out.writeString(weeklyPrice);
        out.writeString(weekendPrice);
        out.writeString(存款);
        out.writeString(minimumAge);
        out.writeString(颜色);
        out.writeString(使);
        out.writeString(位置);
        out.writeString(体形);
        out.writeString(fuelType);
        out.writeString(传输);
        out.writeString(car​​Type);
        out.writeString(模型);
        out.writeString(介绍);

    }

    //这是用来生成你的对象。所有parcelables的必须有一个实现这两种方法CREATOR
    公共静态最终Parcelable.Creator< CarDetail> CREATOR =新Parcelable.Creator< CarDetail>(){
        公共CarDetail createFromParcel(包裹中){
            返回新CarDetail(中);
        }

        公共CarDetail [] newArray(INT尺寸){
            返回新CarDetail【尺寸】;
        }
    };

    //例如构造函数一个包裹,让您填充它的值的对象
    私人CarDetail(包裹中){
        carId = in.readString();
        carName = in.readString();
        IMAGEURL = in.readString();
        thumbUrl = in.readString();
        dailyPrice = in.readString();
        weeklyPrice = in.readString();
        weekendPrice = in.readString();
        存款= in.readString();
        minimumAge = in.readString();
        颜色= in.readString();
        使= in.readString();
        位置= in.readString();
        体形= in.readString();
        fuelType = in.readString();
        变速箱= in.readString();
        carType = in.readString();
        模型= in.readString();
        说明= in.readString();

    }



 公共无效stopImageLoadTask(){
    task.cancel(真正的);
    Log.d(停止,停止);
}
 

这是片段

 公共类ServiceCarListFragment扩展片段{

私人字符串URL;
私人的ArrayList< CarDetail> carDetailList =新的ArrayList< CarDetail>();
私人CarListAdapter适配器;
私人的ListView mList;
私人ProgressDialog progressDialog;
OnCarListItemSelectedListener mCallback;
私人布尔connectionStatus;

//集装箱活动必须实现此接口
公共接口OnCarListItemSelectedListener {
    公共无效onCarSelected(CarDetail车);
}

@覆盖
公共无效onAttach(活动活动){
    // TODO自动生成方法存根
    super.onAttach(活动);
    //这将确保集装箱活动已实施
    //回调接口。如果不是,它抛出一个异常
    尝试 {
        mCallback =(OnCarListItemSelectedListener)的活动;
    }赶上(ClassCastException异常E){
        抛出新ClassCastException异常(activity.toString()
                +必须实现OnCarListItemSelectedListener);
    }
}





@覆盖
公共无效的onCreate(包savedInstanceState){
    // TODO自动生成方法存根
    super.onCreate(savedInstanceState);
    Log.d(服务,关于创建);
    网址= getActivity()getIntent()getStringExtra(URL)。;
    适配器=新CarListAdapter(getActivity(),carDetailList);

    ConnectionHandler康恩=新ConnectionHandler();
    connectionStatus = conn.connectionStatus(getActivity());

    如果(connectionStatus){

        新DownloadCarDetail()执行(URL);
    }

    其他{
        DialogFragment newFragment =新DialogHandler中(getActivity());
        newFragment.show(getFragmentManager(),互联网);
    }


}

@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
        捆绑savedInstanceState){
    // TODO自动生成方法存根
    Log.d(服务,关于CreateView的);
    视图V = inflater.inflate(R.layout.fragment_service_car_list,集装箱,假);
    mList =(ListView控件)v.findViewById(R.id.list);
    mList.setAdapter(适配器);
    mList.setOnItemClickListener(新OnItemClickListener(){

        @覆盖
        公共无效onItemClick(适配器视图<>母公司,查看selectedView,INT位置,
                长ID){
            // TODO自动生成方法存根
            CarDetail车=(CarDetail)adapter.getItem(位置);
            mCallback.onCarSelected(车);
        }
    });
    返回伏;
}

类DownloadCarDetail扩展的AsyncTask<字符串,字符串,ArrayList的< CarDetail>> {



    @覆盖
    在preExecute保护无效(){
        // TODO自动生成方法存根
        super.on preExecute();
        progressDialog = ProgressDialog.show(getActivity(),NULL,载入中...,真正的);

    }

    @覆盖
    受保护的ArrayList< CarDetail> doInBackground(字符串... PARAMS){
        // TODO自动生成方法存根
        ArrayList的< CarDetail> carDetailList = JsonParser.parseJson(PARAMS [0]);
        返回carDetailList;
    }

    @覆盖
    保护无效onPostExecute(ArrayList中< CarDetail> carDetailList){
        // TODO自动生成方法存根
        //适配器=新CarListAdapter(getActivity(),ServiceCarListFragment.this.carDetailList);
        //mList.setAdapter(adapter);
        progressDialog.dismiss();
        ServiceCarListFragment.this.carDetailList.addAll(carDetailList);
        adapter.notifyDataSetChanged();
        对于(CarDetail车:carDetailList){
            //开始加载图像每辆车
            car.loadImage(适配器);

    }
        carDetailList.clear();
        Log.d(ewgf,将String.valueOf(carDetailList.size()));
 }

}



@覆盖
公共无效的onDestroy(){
    // TODO自动生成方法存根
    super.onDestroy();
    新CarDetail()stopImageLoadTask();
}

}
 

解决方案

公众最终布尔取消(布尔mayInterruptIfRunning)

试图取消对此任务的执行。 这种企图将会失败如果任务已经完成,已经被取消,或无法被取消某些其他原因。如果成功的话,当取消被称为这个任务还没有开始,这个任务不应该运行。如果任务已经启动,则mayInterruptIfRunning参数决定是否执行此任务的线程应以试图阻止该任务被中断。

Android性能优化典范 第5季

使用isCancelled()

公众最终布尔isCancelled()

返回true,如果该任务被取消之前正常完成。 如果您呼叫的任务取消(布尔),此方法返回的值应定期从doInBackground检查(对象[]),以尽快结束任务

Android的 - 取消的AsyncTask强行

检查公认的答案和commonsware在上面的链接的答案

I have created an AsyncTask in a class and i am calling that task from a fragment. The problem is i want to stop the doInBackground method if the fragment is destroyed. To do that i created a method in the class where AsyncTask is written and i used cancel(true) on Asynctask object in that method. When i call this method from fragments onDestroy() the background process is still running. Plz tell me the right way to stop asynctask's doInBackground.

This is the class where asynctask is written

public class CarDetail implements Parcelable{

private String carId;
private String carName;
private String imageUrl;
private String thumbUrl;
private String dailyPrice;
private String weeklyPrice;
private String weekendPrice;
private String deposit;
private String minimumAge;
private String color;
private String make;
private String location;
private String bodyType;
private String fuelType;
private String transmission;
private String carType;
private String model;
private String description;
private Bitmap image;
private Bitmap thumbImage;
private CarListAdapter carAdapter;
private ImageLoadTask task = new ImageLoadTask();

public CarDetail() {
    super();
    // TODO Auto-generated constructor stub
}

public CarDetail(String carId, String carName, String imageUrl,
        String thumbUrl, String dailyPrice, String weeklyPrice,
        String weekendPrice, String deposit, String minimumAge,
        String color, String make, String location, String bodyType,
        String fuelType, String transmission, String carType, String model,
        String description) {
    super();
    this.carId = carId;
    this.carName = carName;
    this.imageUrl = imageUrl;
    this.thumbUrl = thumbUrl;
    this.dailyPrice = dailyPrice;
    this.weeklyPrice = weeklyPrice;
    this.weekendPrice = weekendPrice;
    this.deposit = deposit;
    this.minimumAge = minimumAge;
    this.color = color;
    this.make = make;
    this.location = location;
    this.bodyType = bodyType;
    this.fuelType = fuelType;
    this.transmission = transmission;
    this.carType = carType;
    this.model = model;
    this.description = description;

    // TO BE LOADED LATER - OR CAN SET TO A DEFAULT IMAGE
    this.image = null;
    this.thumbImage = null;
}

public String getCarId() {
    return carId;
}

public void setCarId(String carId) {
    this.carId = carId;
}

public String getCarName() {
    return carName;
}

public void setCarName(String carName) {
    this.carName = carName;
}

public String getImageUrl() {
    return imageUrl;
}

public void setImageUrl(String imageUrl) {
    this.imageUrl = imageUrl;
}

public String getThumbUrl() {
    return thumbUrl;
}

public void setThumbUrl(String thumbUrl) {
    this.thumbUrl = thumbUrl;
}

public String getDailyPrice() {
    return dailyPrice;
}

public void setDailyPrice(String dailyPrice) {
    this.dailyPrice = dailyPrice;
}

public String getWeeklyPrice() {
    return weeklyPrice;
}

public void setWeeklyPrice(String weeklyPrice) {
    this.weeklyPrice = weeklyPrice;
}

public String getWeekendPrice() {
    return weekendPrice;
}

public void setWeekendPrice(String weekendPrice) {
    this.weekendPrice = weekendPrice;
}

public String getDeposit() {
    return deposit;
}

public void setDeposit(String deposit) {
    this.deposit = deposit;
}

public String getMinimumAge() {
    return minimumAge;
}

public void setMinimumAge(String minimumAge) {
    this.minimumAge = minimumAge;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public String getMake() {
    return make;
}

public void setMake(String make) {
    this.make = make;
}

public String getLocation() {
    return location;
}

public void setLocation(String location) {
    this.location = location;
}

public String getBodyType() {
    return bodyType;
}

public void setBodyType(String bodyType) {
    this.bodyType = bodyType;
}

public String getFuelType() {
    return fuelType;
}

public void setFuelType(String fuelType) {
    this.fuelType = fuelType;
}

public String getTransmission() {
    return transmission;
}

public void setTransmission(String transmission) {
    this.transmission = transmission;
}

public String getCarType() {
    return carType;
}

public void setCarType(String carType) {
    this.carType = carType;
}

public String getModel() {
    return model;
}

public void setModel(String model) {
    this.model = model;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public Bitmap getImage() {
    return image;
}

public void setImage(Bitmap image) {
    this.image = image;
}

public Bitmap getThumbImage() {
    return thumbImage;
}

public void setThumbImage(Bitmap thumbImage) {
    this.thumbImage = thumbImage;
}

 public void loadImage(CarListAdapter carAdapter) {
        // HOLD A REFERENCE TO THE ADAPTER
        this.carAdapter = carAdapter;
        if (thumbUrl != null && !thumbUrl.equals("")) {
            //new ImageLoadTask().execute(thumbUrl);

            task.execute(thumbUrl);
        }
 }

    // ASYNC TASK TO AVOID CHOKING UP UI THREAD
    private class ImageLoadTask extends AsyncTask<String, String, Bitmap> {

        @Override
        protected void onPreExecute() {
            Log.i("ImageLoadTask", "Loading image...");
        }

        // PARAM[0] IS IMG URL
        protected Bitmap doInBackground(String... param) {
            Log.i("ImageLoadTask", "Attempting to load image URL: " + param[0]);
            try {
                Bitmap b = JsonParser.downloadBitmap(param[0]);
                return b;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        protected void onProgressUpdate(String... progress) {
            // NO OP
        }

        protected void onPostExecute(Bitmap ret) {
            if (ret != null) {
                Log.i("ImageLoadTask", "Successfully loaded " + carName + " image");
                image = ret;
                if (carAdapter != null) {
                    // WHEN IMAGE IS LOADED NOTIFY THE ADAPTER
                    carAdapter.notifyDataSetChanged();
                }
            } else {
                Log.e("ImageLoadTask", "Failed to load " + carName + " image");
            }
        }
    }


    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(carId);
        out.writeString(carName);
        out.writeString(imageUrl);
        out.writeString(thumbUrl);
        out.writeString(dailyPrice);
        out.writeString(weeklyPrice);
        out.writeString(weekendPrice);
        out.writeString(deposit);
        out.writeString(minimumAge);
        out.writeString(color);
        out.writeString(make);
        out.writeString(location);
        out.writeString(bodyType);
        out.writeString(fuelType);
        out.writeString(transmission);
        out.writeString(carType);
        out.writeString(model);
        out.writeString(description);

    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<CarDetail> CREATOR = new Parcelable.Creator<CarDetail>() {
        public CarDetail createFromParcel(Parcel in) {
            return new CarDetail(in);
        }

        public CarDetail[] newArray(int size) {
            return new CarDetail[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private CarDetail(Parcel in) {
        carId = in.readString();
        carName = in.readString();
        imageUrl = in.readString();
        thumbUrl = in.readString();
        dailyPrice = in.readString();
        weeklyPrice = in.readString();
        weekendPrice = in.readString();
        deposit = in.readString();
        minimumAge = in.readString();
        color = in.readString();
        make = in.readString();
        location  = in.readString();
        bodyType = in.readString();
        fuelType = in.readString();
        transmission = in.readString();
        carType = in.readString();
        model = in.readString();
        description = in.readString();

    }



 public void stopImageLoadTask(){
    task.cancel(true);
    Log.d("stop", "stop");
}

This is the fragment

 public class ServiceCarListFragment extends Fragment {

private String url;
private ArrayList<CarDetail> carDetailList = new ArrayList<CarDetail>();
private CarListAdapter adapter;
private ListView mList ;
private ProgressDialog progressDialog;
OnCarListItemSelectedListener mCallback;
private boolean connectionStatus;

// Container Activity must implement this interface
public interface OnCarListItemSelectedListener {
    public void onCarSelected(CarDetail car);
}

@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        mCallback = (OnCarListItemSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnCarListItemSelectedListener");
    }
}





@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    Log.d("Services", "On Create");
    url = getActivity().getIntent().getStringExtra("url");
    adapter = new CarListAdapter(getActivity() , carDetailList);

    ConnectionHandler conn = new ConnectionHandler();
    connectionStatus = conn.connectionStatus(getActivity());

    if(connectionStatus){

        new DownloadCarDetail().execute(url);
    }

    else{
        DialogFragment newFragment = new DialogHandler(getActivity());
        newFragment.show(getFragmentManager(), "internet");
    }


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    Log.d("Services", "On CreateView");
    View v = inflater.inflate(R.layout.fragment_service_car_list, container,false);
    mList = (ListView)v.findViewById(R.id.list);
    mList.setAdapter(adapter);  
    mList.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View selectedView, int position,
                long id) {
            // TODO Auto-generated method stub
            CarDetail car = (CarDetail)adapter.getItem(position);
            mCallback.onCarSelected(car);
        }
    });
    return v;
}

class DownloadCarDetail extends AsyncTask<String, String, ArrayList<CarDetail>>{



    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        progressDialog = ProgressDialog.show(getActivity(), null, "Loading...",true);

    }

    @Override
    protected ArrayList<CarDetail> doInBackground(String... params) {
        // TODO Auto-generated method stub
        ArrayList<CarDetail> carDetailList = JsonParser.parseJson(params[0]);
        return carDetailList;
    }

    @Override
    protected void onPostExecute(ArrayList<CarDetail> carDetailList) {
        // TODO Auto-generated method stub
        //adapter = new CarListAdapter(getActivity(),ServiceCarListFragment.this.carDetailList);
        //mList.setAdapter(adapter);
        progressDialog.dismiss();
        ServiceCarListFragment.this.carDetailList.addAll(carDetailList);
        adapter.notifyDataSetChanged();
        for (CarDetail car : carDetailList) {
            // START LOADING IMAGES FOR EACH CAR
            car.loadImage(adapter);

    }
        carDetailList.clear();
        Log.d("ewgf", String.valueOf(carDetailList.size()));
 }

}



@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    new CarDetail().stopImageLoadTask();
}

}

解决方案

public final boolean cancel (boolean mayInterruptIfRunning)

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.

Use isCancelled()

public final boolean isCancelled ()

Returns true if this task was cancelled before it completed normally. If you are calling cancel(boolean) on the task, the value returned by this method should be checked periodically from doInBackground(Object[]) to end the task as soon as possible.

Android - Cancel AsyncTask Forcefully

Check the accepted answer and the answer by commonsware in the above link