我有2个DownloadManager的简单实现和自定义下载任务:


DownloadManager

public void onCreate(Bundle savedInstanceState) {
 ...
 mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
}

private void startDownload(String link)
 Uri uri=Uri.parse(link);

 DownloadManager.Request req = new DownloadManager.Request(uri);

 req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
        | DownloadManager.Request.NETWORK_MOBILE)
        .setAllowedOverRoaming(false)
        .setVisibleInDownloadsUi(false)
        .setTitle(getString(R.string.app_name))
        .setDescription(getString(R.string.waiting_for_downloading))
        .setDestinationInExternalPublicDir(dataPath,fileName);

 lastDownload = mDownloadManager.enqueue(req);
}

private void queryStatus() {
 Cursor c = mDownloadManager.query(new DownloadManager.Query().setFilterById(lastDownload));

 if (c == null) return;

 switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
        case DownloadManager.STATUS_FAILED:
            downloadError();
            break;
        case DownloadManager.STATUS_RUNNING:
            ...
            break;
        case DownloadManager.STATUS_SUCCESSFUL:
            ...
            break;
        default: break;
    }
    c.close();
 }

自定义下载任务

new AsyncTask<String, Void, Void>() {
 @Override
  protected Void doInBackground(String... params) {
    try {
      URL url = new URL(params[0]);
      InputStream input = new BufferedInputStream(url.openStream());
      OutputStream output = new FileOutputStream(saveFile);
      byte data[] = new byte[1024];

      while ((count = input.read(data)) != -1) {
          output.write(data, 0, count);
      }
      output.flush();
      output.close();
      input.close();

    } catch (Exception e) {
         downloadError();
        }
   return null;
  }
}



在一般情况下,两种方法都可以,但是在某些设备上(例如前小米android 6),DownloadManager的运行速度要慢2-3倍,或者出现DownloadManager.STATUS_FAILED错误。但为什么? DownloadManager不稳定吗?还是关于设置的秘密?

附言:我想使用DownloadManager是因为我不应该自己进行自定义,例如设置允许的网络或在通知区域显示进度。

更新v0.1

1)我有一个叫queryStatus()的处理程序,每1秒检查一次。

2)尝试使用联系电话连接到另一个wi-fi网络-DownloadManager可以正常运行,但是自定义实现失败...

更新v0.2

尝试从AsyncTask调用Service下载器(如果用户关闭应用而不取消过程,则继续下载),通过BroadcastReceiver + sendBreadcase()Service调用进行UI更新-结果:下载速度减慢了几倍现在(不时地)出现了unexpected end of stream异常。 [尝试从Activity拨打电话时下载的相同文件]

更新v0.3

忘记注意:DownloadManager失败,出现1008原因= ERROR_CANNOT_RESUME

也尝试过ION。看起来是否比DownloadManager更好,但有时出现错误End of data reached before content length was read: 70385664/77217546

因此,仍在寻找最稳定的解决方案...

最佳答案

好的...通过不同的Wi-Fi连接和设备集通过了许多测试。 ION给出最稳定的结果。

关于android - DownloadManager与InputStream.read(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43249633/

10-10 21:10