简体   繁体   English

isCancelled()在android异步任务中不起作用

[英]isCancelled() not Working in android Async Task

I want to cancel a downloading file using async task, i tried below code, here isCancelled() method is not working, can any one suggest how can i stop download. 我想使用异步任务取消下载文件,我尝试了下面的代码,这里isCancelled()方法不起作用,有人可以建议我如何停止下载。

vid1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            down d1=new down();
        if(vid1.getText().toString().equals("Start")){
            Log.v("Vid 1", "Vid 1");
            vid1.setText("Pause");
            d1.execute(url1,"one");

        }else if(vid1.getText().toString().equals("Pause")){
            vid1.setText("Start");
            Log.v("Vid 1 Else", "Vid 1 Else");
            if(d1!=null && d1.getStatus()!=AsyncTask.Status.FINISHED){
            d1.cancel(true);
            }

        }
        }
    });

vid2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Log.v("Vid 2", "Vid 2");
            // TODO Auto-generated method stub
            down d2=new down();
        if(vid2.getText().toString().equals("Start")){
            vid2.setText("Pause");
            d2.execute(url2,"two");


        }else if(vid2.getText().toString().equals("Pause")){
            vid2.setText("Start");
            Log.v("Vid 2 Else", "Vid 2 Else ");
            d2.cancel(true);
        }
        }
    });


}
private class down extends AsyncTask<String, Void, String>{
    RandomAccessFile output ;

    boolean cancel=false;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub

        Log.v("Pre Execute", "Pre Execute");
    }


    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub


        File outputFileCache=new File(Environment.getExternalStorageDirectory()+"/pau/"+params[1]+".mp4");

    try {

        Long download_ok = null ;
        int fileLength;
         URL url = new URL(params[0]);

         HttpURLConnection connection  = (HttpURLConnection) url.openConnection() ;


         if (outputFileCache.exists())
         {
             Log.v(">>>>>>", "Exists");
             connection.setAllowUserInteraction(true);
             connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-");
         }

         connection.setConnectTimeout(14000);
         connection.setReadTimeout(20000);
         connection.connect();

         if (connection.getResponseCode() / 100 != 2)
             throw new Exception("Invalid response code!");

         else
         {
             String connectionField = connection.getHeaderField("content-range");

             if (connectionField != null)
             {
                 String[] connectionRanges = connectionField.substring("bytes=".length()).split("-");
                 download_ok = Long.valueOf(connectionRanges[0]);
                 Log.v("download ok", ""+download_ok);
             }

             if (connectionField == null && outputFileCache.exists())
                 outputFileCache.delete();
if(download_ok==null){
download_ok=(long) 0;
}
             fileLength = (int) (connection.getContentLength() + download_ok);
             Log.v("file length", ""+fileLength);
             input = new BufferedInputStream(connection.getInputStream());
             output = new RandomAccessFile(outputFileCache, "rw");
             output.seek(download_ok);

             byte data[] = new byte[1024];
             int count = 0;
             int __progress = 0;

             while ((count = input.read(data, 0, 1024)) != -1 && __progress!=100) 
             {
                 Log.v(">>>>>>>>>>>progress cancelled", "<<<<<<<<<"+isCancelled());
                 if(isCancelled()){
                        Log.v(">>>>>>>>>>>>>>>>>>>>>>>>>>>", "<<<<<<<<<"+isCancelled());

                     break;
                 }else{
                     download_ok += count;

                 output.write(data, 0, count);

                 __progress = (int) ((download_ok * 100) / fileLength);
                 }

             }

             output.close();
             input.close();
        }

    } catch (Exception e) {
            e.printStackTrace();

    }

    return null;

    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
    }

Found your problem: You are creating a new instance of the Asynctask with every click, eg 发现问题所在:您每次点击都在创建Asynctask的新实例,例如

down d2=new down();

This means that you are calling cancel on a different AsyncTask object. 这意味着您要在另一个AsyncTask对象上调用cancel。 You need to move this line into your check for the start click and also use a field and not a local variable ie 您需要将此行移至开始点击检查中,并使用一个字段而不是局部变量,即

 if(vid2.getText().toString().equals("Start")) {
     d2 = new down();
     vid2.setText("Pause");
     d2.execute(url2,"two");
}

where d2 is set in your class. 在您的班级中设置d2的位置。 Also note that class names should always start with capital letters, ie class Down instead of class down . 另请注意,类名应始终以大写字母开头,即class Down而不是class down

EDIT 编辑

You can store the Asynctask in a global class array that is equal in length to the number of videos. 您可以将Asynctask存储在长度与视频数量相等的全局类数组中。

Down downTasks[] = new Down[TOTAL VIDEOS];

Then you initialise the Views, similar to what you already did, here shown for one View 然后您初始化视图,类似于您已经做过的,此处显示的是一个View

vid1.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        if(vid1.getText().toString().equals("Start")){
            Log.v("Vid 1", "Vid 1");
            vid1.setText("Pause");
            downTasks[0] = new down();
            downTasks[0].execute(url1,"one");
        }
        else if(vid1.getText().toString().equals("Pause")){
            vid1.setText("Start");
            Log.v("Vid 1 Else", "Vid 1 Else");
            if(downTasks[0]!=null && downTasks[0].getStatus()!=AsyncTask.Status.FINISHED){
                downTasks[0].cancel(true);
            }
        }
    }
});

Note that this code is quite redundant because you rewrite almost exactly the same code for every View , this can be nicely refactored with a for loop, but I leave that as an exercise for you if you feel like it. 请注意,此代码是非常多余的,因为您为每个View重写几乎完全相同的代码,可以使用for循环很好地对其进行重构,但是如果您愿意,我可以将其作为练习留给您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM