下载管理器与 InputStream.read()
DownloadManager vs InputStream.read()
我有 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;
}
}
在一般情况下,这两种方法都可以正常工作,但在某些设备上 (对于 ex xiaomi android 6) DownloadManager
工作速度慢 2-3 倍或我收到 DownloadManager.STATUS_FAILED
错误。但为什么? DownloadManager
不稳定吗?还是关于设置?
p.s:我想使用 DownloadManager
因为自定义我不应该自己实现,比如设置允许的网络或在通知区域显示进度。
更新 v0.1
1) 我有处理程序调用 queryStatus()
每 1 秒检查一次。
2) 尝试使用 nexus phone 连接到另一个 wi-fi
网络 - DownloadManager
工作正常,但自定义实现失败...
更新 v0.2
尝试从 Service
调用 AsyncTask
下载程序(以在用户关闭应用程序而不取消进程的情况下继续下载)、UI通过 BroadcastReceiver
+ 来自 Service
的 sendBreadcase()
调用进行更新 - 结果:下载速度变慢了好几倍,现在(不时)我收到了 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
授予最稳定的结果。
我有 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; } }
在一般情况下,这两种方法都可以正常工作,但在某些设备上 (对于 ex xiaomi android 6) DownloadManager
工作速度慢 2-3 倍或我收到 DownloadManager.STATUS_FAILED
错误。但为什么? DownloadManager
不稳定吗?还是关于设置?
p.s:我想使用 DownloadManager
因为自定义我不应该自己实现,比如设置允许的网络或在通知区域显示进度。
更新 v0.1
1) 我有处理程序调用 queryStatus()
每 1 秒检查一次。
2) 尝试使用 nexus phone 连接到另一个 wi-fi
网络 - DownloadManager
工作正常,但自定义实现失败...
更新 v0.2
尝试从 Service
调用 AsyncTask
下载程序(以在用户关闭应用程序而不取消进程的情况下继续下载)、UI通过 BroadcastReceiver
+ 来自 Service
的 sendBreadcase()
调用进行更新 - 结果:下载速度变慢了好几倍,现在(不时)我收到了 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
授予最稳定的结果。