DownloadManager和InputStream.read()的区别

3
我有两种简单实现 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();
     }
    
  • custom download task

    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;
      }
    }
    
一般情况下,这两种方法都可以正常工作,但是在某些设备上 (例如小米安卓6)DownloadManager 的速度会变慢2-3倍,或者会出现 DownloadManager.STATUS_FAILED 错误。但是为什么呢?是因为DownloadManager 不稳定吗?还是与设置有关?
附注:我想使用DownloadManager,因为我不需要自己实现允许的网络设置或在通知区域显示进度等自定义功能。
更新v0.1
1)我有一个处理程序,每秒调用queryStatus() 检查一次。
2)尝试连接到另一个 wi-fi 网络与 Nexus 手机 - DownloadManager 可以正常工作,但自定义实现失败...
更新v0.2
尝试从Service调用AsyncTask downloader(以便在用户关闭应用程序而未取消过程的情况下继续下载),通过BroadcastReceiver + Service中的sendBroadcast()调用来更新UI - 结果:下载速度变慢了几倍,并且现在(时不时地)会出现“意外流结束”的异常。[当从Activity调用时,尝试使用相同的文件进行下载]
更新v0.3
忘记注意:DownloadManager失败,原因是1008 = ERROR_CANNOT_RESUME
也尝试了ION。看起来比DownloadManager更好,但有时会出现错误End of data reached before content length was read: 70385664/77217546
因此,仍在寻找最稳定的解决方案...
1个回答

0

好的...我们进行了很多测试,使用不同的Wi-Fi连接和设备组合。 ION 提供了最稳定的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接