/** notifyDeleteDownloadFilesCompleted */
  private void notifyDeleteDownloadFilesCompleted() {
    if (mIsNotifyFinish.get()) {
      return;
    }

    if (mIsNotifyFinish.compareAndSet(false, true)) {

      OnDeleteDownloadFilesListener.MainThreadHelper.onDeleteDownloadFilesCompleted(
          mDownloadFilesNeedDelete, mDownloadFilesDeleted, mOnDeleteDownloadFilesListener);

      mIsStop = true; // the task is finish

      int failedSize = mDownloadFilesNeedDelete.size() - mDownloadFilesDeleted.size();

      Log.d(
          TAG,
          TAG
              + ".run 批量删除文件主任务和其它相关任务全部【已结束】,总共需要删除:"
              + mDownloadFilesNeedDelete.size()
              + ",已删除:"
              + mDownloadFilesDeleted.size()
              + ",失败:"
              + failedSize
              + ",跳过:"
              + mDownloadFilesSkip.size()
              + ",跳过数量是否等于失败数量:"
              + (failedSize == mDownloadFilesSkip.size()));
    }
  }
  /** notifyDeleteDownloadFilesPrepared */
  private void notifyDeleteDownloadFilesPrepared() {

    Log.d(TAG, TAG + ".run 准备批量删除,大小:" + mDownloadFilesNeedDelete.size());

    OnDeleteDownloadFilesListener.MainThreadHelper.onDeleteDownloadFilesPrepared(
        mDownloadFilesNeedDelete, mOnDeleteDownloadFilesListener);
  }
    @Override
    public void onDeleteDownloadFileSuccess(DownloadFileInfo downloadFileDeleted) {

      String url = null;
      if (downloadFileDeleted != null) {
        url = downloadFileDeleted.getUrl();
      }

      synchronized (mLock) { // lock
        // delete succeed
        mDownloadFilesDeleted.add(downloadFileDeleted);
      }

      Log.d(
          TAG,
          TAG
              + ".run 删除单个成功,已删除数量:"
              + mDownloadFilesDeleted.size()
              + ",总共需要删除数量"
              + mDownloadFilesNeedDelete.size()
              + ",url:"
              + url);

      if (mDownloadFilesDeleted.size() + mDownloadFilesSkip.size()
          == mDownloadFilesNeedDelete.size()) {
        // complete, notify caller
        notifyDeleteDownloadFilesCompleted();
      }
    }
  /** notifyDeletingDownloadFiles */
  private void notifyDeletingDownloadFiles(DownloadFileInfo downloadFileInfo) {

    String url = null;
    if (downloadFileInfo != null) {
      url = downloadFileInfo.getUrl();
    }

    Log.d(TAG, TAG + ".run 准备删除单个,url:" + url);

    OnDeleteDownloadFilesListener.MainThreadHelper.onDeletingDownloadFiles(
        mDownloadFilesNeedDelete,
        mDownloadFilesDeleted,
        mDownloadFilesSkip,
        downloadFileInfo,
        mOnDeleteDownloadFilesListener);
  }
    @Override
    public void onDeleteDownloadFileFailed(
        DownloadFileInfo downloadFileInfo, DeleteDownloadFileFailReason failReason) {

      String url = null;
      if (downloadFileInfo != null) {
        url = downloadFileInfo.getUrl();
      }

      String msg = null;
      if (failReason != null) {
        msg = failReason.getMessage();
      }

      Log.d(
          TAG,
          TAG
              + ".run 删除单个成功,已删除数量:"
              + mDownloadFilesDeleted.size()
              + ",总共需要删除数量"
              + mDownloadFilesNeedDelete.size()
              + ",失败原因:"
              + msg
              + ",url:"
              + url);

      synchronized (mLock) { // lock
        // delete failed
        mDownloadFilesSkip.add(downloadFileInfo);
      }

      if (mDownloadFilesDeleted.size() + mDownloadFilesSkip.size()
          == mDownloadFilesNeedDelete.size()) {
        // complete, notify caller
        notifyDeleteDownloadFilesCompleted();
      }
    }
  @Override
  public void run() {

    try {
      mDownloadFilesNeedDelete.clear();
      mDownloadFilesDeleted.clear();
      mDownloadFilesSkip.clear();

      for (String url : mUrls) {
        if (!UrlUtil.isUrl(url)) {
          continue;
        }
        DownloadFileInfo downloadFileInfo = getDownloadFile(url);
        if (downloadFileInfo != null) {
          //                    synchronized (mLock) {//lock
          mDownloadFilesNeedDelete.add(downloadFileInfo);
          //                    }
        }
      }

      // prepare to delete
      notifyDeleteDownloadFilesPrepared();

      // delete every single download file listener
      final OnDeleteDownloadFileListener onDeleteEverySingleDownloadFileListener =
          new OnDeleteSingleDownloadFileListener();

      // delete every single one
      for (int i = 0; i < mDownloadFilesNeedDelete.size(); i++) {

        DownloadFileInfo downloadFileInfo = mDownloadFilesNeedDelete.get(i);
        if (downloadFileInfo == null) {
          // skip one
          synchronized (mLock) { // lock
            mDownloadFilesSkip.add(downloadFileInfo);
          }
          continue;
        }

        final String finalUrl = downloadFileInfo.getUrl();

        // if the task stopped,notify completed
        if (isStopped()) {

          Log.d(TAG, TAG + ".run 批量删除任务被取消,无法继续删除,任务即将结束");

          // goto finally, notifyDeleteDownloadFilesCompleted()
          return;
        }

        // downloading
        if (mDownloadTaskPauseable.isDownloading(finalUrl)) {

          Log.d(TAG, TAG + ".run 需要先暂停单个下载任务后删除,url:" + finalUrl);

          // pause first
          mDownloadTaskPauseable.pause(
              finalUrl,
              new OnStopFileDownloadTaskListener() {
                @Override
                public void onStopFileDownloadTaskSucceed(String url) {

                  Log.d(TAG, TAG + ".run 暂停单个下载任务成功,开始删除,url:" + finalUrl);

                  // if the task stopped,notify completed
                  if (isStopped()) {

                    Log.d(TAG, TAG + ".run 批量删除任务被取消,无法继续删除,任务即将结束");

                    // notify caller
                    notifyDeleteDownloadFilesCompleted();
                    return;
                  }

                  // stopped, continue delete
                  runSingleDeleteTask(finalUrl, onDeleteEverySingleDownloadFileListener, false);
                }

                @Override
                public void onStopFileDownloadTaskFailed(
                    String url, StopDownloadFileTaskFailReason failReason) {

                  // if the task stopped, notify completed
                  if (isStopped()) {

                    Log.d(TAG, TAG + ".run 批量删除任务被取消,无法继续删除,任务即将结束");

                    // notify caller
                    notifyDeleteDownloadFilesCompleted();
                    return;
                  }

                  if (failReason != null) {
                    if (StopDownloadFileTaskFailReason.TYPE_TASK_HAS_BEEN_STOPPED.equals(
                        failReason.getType())) {
                      // stopped, continue delete
                      runSingleDeleteTask(finalUrl, onDeleteEverySingleDownloadFileListener, false);
                      return;
                    }
                  }

                  Log.d(TAG, TAG + ".run 暂停单个下载任务失败,无法删除,url:" + finalUrl);

                  // failed
                  synchronized (mLock) { // lock
                    mDownloadFilesSkip.add(getDownloadFile(finalUrl));
                  }
                }
              });
        } else {
          // run delete task directly
          runSingleDeleteTask(finalUrl, onDeleteEverySingleDownloadFileListener, true);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
      // error, ignore
    } finally {

      if (isStopped()) {
        // notify caller
        notifyDeleteDownloadFilesCompleted();
      }

      Log.d(TAG, TAG + ".run 批量删除文件主任务【已结束】,但是通过暂停下载中的文件删除任务可能还没有结束");
    }
  }