为什么任务取消后,无法重新重头下载

为什么任务取消后,无法重新重头下载

package com.example.asynctask;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
/*实现功能:(1)网络下载三个文件
* (2)下载按钮
* (3)暂停下载按钮
* (3)取消下载按钮*/
public class AsncDownloadHomework extends AppCompatActivity implements View.OnClickListener{
   public static final int INIT_PROGRESS = 0;
   Button bt_start, bt_pause,bt_cancel;
   TextView tv;
   ProgressBar progressB;
   int code;
   public static final int NOT_START_TASK=0;
   public static final int START_TASK=1;
   public static final int PAUSE_TASK=-1;
   public static final String APK_URL = "http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk";

   DownloadAsyncTask downloadAsyncTask;//声明下载任务对象
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.downloadhomework);
       initView();//初始化视图
       initData();//初始化数据

   } private void initData() {
       code=NOT_START_TASK;
       progressB.setMax(100);
       progressB.setProgress(0);
       bt_pause.setEnabled(false);//暂停按钮设为“不可点击”
       bt_cancel.setEnabled(false);//取消按钮为“不可点击”

   }

   private void initView() {
       bt_start = findViewById(R.id.bt_start);
       bt_pause = findViewById(R.id.bt_pause);
       bt_cancel=findViewById(R.id.bt_cancel);
       bt_start.setOnClickListener(this);
       bt_pause.setOnClickListener(this);
       bt_cancel.setOnClickListener(this);
       tv = findViewById(R.id.tv_showProgressBar);
       progressB = findViewById(R.id.progressb);
   }

   @Override
   public void onClick(View v) {
       switch (v.getId()){
       case R.id.bt_start:       //开始下载按钮监听器
           if(code==NOT_START_TASK)//下载任务没有开始
           {   downloadAsyncTask = new DownloadAsyncTask(PAUSE_TASK);//新建下载任务
               downloadAsyncTask.execute(APK_URL, APK_URL, APK_URL);//开始下载
           }
           code=START_TASK;
           downloadAsyncTask.setDownloadCode(code);//设置开始下载参数
           bt_pause.setEnabled(true);
           bt_cancel.setEnabled(true);
           break;
           case R.id.bt_pause:        //暂停下载按钮监听器
               code=PAUSE_TASK;
               downloadAsyncTask.setDownloadCode(code);
               break;
           case R.id.bt_cancel://取消下载按钮监听器
               downloadAsyncTask.cancel(true);//发送取消下载任务
               break;
   }


   }


   /**
    * String 入参
    * Integer 进度
    * Boolean 返回值
    */
   public  class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
       String mFilePath;
       int contentLength;
       int downloadSize;
       int downloadCode;
       int i=0;

       public int getDownloadCode() {
           return downloadCode;
       }

       public void setDownloadCode(int downloadCode) {
           this.downloadCode = downloadCode;
       }

       public DownloadAsyncTask(int downloadCode) {
           this.setDownloadCode(downloadCode);
   }

       /**
        * 在异步任务之前,在主线程中
        */
       @Override
       protected void onPreExecute() {
           super.onPreExecute();
           // 可操作UI  类似淘米,之前的准备工作
           bt_start.setText(R.string.bt_start_a_task);
           bt_pause.setText(R.string.bt_pause_task);
           bt_pause.setEnabled(false);
           progressB.setProgress(INIT_PROGRESS);
       }

       /**
        * 在另外一个线程中处理事件
        *
        * @param params 入参  煮米
        * @return 结果
        */
       @Override
       protected Boolean doInBackground(String... params) {
           while(downloadCode==PAUSE_TASK)//暂停下载
           {
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
                   return  false;
               }
           }
           if (params != null && params.length > 0) {
               for( i=0;i<params.length;i++){
                   if(isCancelled())return false;  //接到下载任务取消命令,直接返回下载失败
                   while(downloadCode==PAUSE_TASK)//暂停下载
                   {
                       try {
                           Thread.sleep(1000);
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                           return  false;
                       }
                   }
               String apkUrl = params[i];
                contentLength=params.length;
                   // 下载地址准备
                   mFilePath = Environment.getExternalStorageDirectory()
                           + File.separator + "imooc"+Integer.toString(i)+".apk";
               try {
                   // 构造URL
                   URL url = new URL(apkUrl);
                   // 构造连接,并打开
                   URLConnection urlConnection = url.openConnection();
                   InputStream inputStream = urlConnection.getInputStream();

                   // 获取了下载内容的总长度
                  // contentLength = urlConnection.getContentLength();

                   // 对下载地址进行处理
                   File apkFile = new File(mFilePath);
                   if (apkFile.exists()) {
                       boolean result = apkFile.delete();
                       if (!result) {
                           return false;
                       }
                   }

                   // 已下载的大小
                   downloadSize = 0;

                   // byte数组
                   byte[] bytes = new byte[1024];

                   int length;

                   // 创建一个输入管道
                   OutputStream outputStream = new FileOutputStream(mFilePath);

                   // 不断的一车一车挖土,走到挖不到为止
                   while ((length = inputStream.read(bytes)) != -1) {
                       // 挖到的放到我们的文件管道里
                       outputStream.write(bytes, 0, length);
                       // 累加我们的大小
                       downloadSize += length;
                       // 发送进度
                       publishProgress((i+1)*100 / params.length);
                       try {
                           Thread.sleep(500);//延时下载速度,方便清楚观察进度
                       } catch (InterruptedException e) {
                           e.printStackTrace();return false;
                       }
                   }

                   inputStream.close();
                   outputStream.close();
               } catch (IOException e) {
                   e.printStackTrace();
                   return false;
               }
           }

           } else {
               return false;
           }
           return true;
       }

       @Override
       protected void onPostExecute(Boolean result) {
           super.onPostExecute(result);
           // 也是在主线程中 ,执行结果处理
           if (result) {
          code=NOT_START_TASK;     i=0; //准备下一次重新下载数据
               bt_pause.setEnabled(false);//下载完成后,暂停下载按钮不可点
               bt_cancel.setEnabled(false);//下载完成后,取消下载按钮不可点
               tv.setText("下载完成" + mFilePath );
           }
           else //result=false,下载失败
               {
               if(isCancelled()) {tv.setText("任务已经取消");}
               else tv.setText("下载失败");
           }
       }
       @Override
       protected void onProgressUpdate (Integer...values){
           super.onProgressUpdate(values);
           // 收到进度,然后处理: 也是在UI线程中。
          if (values != null && values.length > 0) {
              if(downloadCode==PAUSE_TASK){
                  tv.setText("已经暂停下载"+",已下载" + (i+1) + "个,下载进度" + values[0] + "%");}
                  else
                      {
                          progressB.setProgress(values[0]);
                  tv.setText("文件数" + contentLength + ",已下载" + (i + 1) + "个,下载进度" + values[0] + "%");
              }
           }
       }

       @Override
       protected void onCancelled(Boolean aBoolean) {
           super.onCancelled(aBoolean);
           if(isCancelled()&aBoolean)//异步任务取消
           {
               tv.setText("任务已经取消");
               bt_pause.setEnabled(false);
               bt_cancel.setEnabled(false);
               code=NOT_START_TASK;
           }
       }
   }
}

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕雪 2018-12-13 11:48:30

一个对象,execute只能调一次哦。除非你再 new DownloadAsyncTask();一下才行。一个任务只能执行一次,取消了就是取消了。再开始就得从头再来一次。祝:学习愉快

  • 提问者 慕运维0750787 #1
    已经重新new了, case R.id.bt_start: //开始下载按钮监听器 if(code==NOT_START_TASK)//下载任务没有开始 { downloadAsyncTask = new DownloadAsyncTask(PAUSE_TASK);//新建下载任务 downloadAsyncTask.execute(APK_URL, APK_URL, APK_URL);//开始下载 } code=START_TASK; downloadAsyncTask.setDownloadCode(code);//设置开始下载参数 bt_pause.setEnabled(true); bt_cancel.setEnabled(true); break; 完全下载后是可以重新开始的。只是取消之后不可以,而且取消之后也没有显示已经取消下载,没有按我设定的执行。 protected void onCancelled(Boolean aBoolean) { super.onCancelled(aBoolean); if(isCancelled()&aBoolean)//异步任务取消 { tv.setText("任务已经取消"); bt_pause.setEnabled(false); bt_cancel.setEnabled(false); code=NOT_START_TASK; } }
    2018-12-13 14:24:15
  • 提问者 慕运维0750787 #2
    我已经解决了。原因不在于这个,因为本身每一次点击就新建了一个对象。我想知道,isCancelled==true时,protected void onCancelled(Boolean aBoolean)的参数aBoolean是多少?是否也是true
    2018-12-13 15:20:17
  • 好帮手慕雪 回复 提问者 慕运维0750787 #3
    嗯,是的,onCancelled()中的参数就是你目前是否已经任务取消了。
    2018-12-13 16:16:43
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
Android网络操作与数据存储2018版
  • 参与学习           人
  • 提交作业       307    份
  • 解答问题       1613    个

本专题是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理。介绍了Android内外部文件存储、轻量级数据库SQLite的使用。利用屏幕适配、状态保持、百度地图解决实际问题。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师