我在这里问了一个类似的问题AsyncTask和Progressbar。
我正在做的是我正在调度下载两个以上的文件一个接一个在后台AsyncTask..UI线程可能在任何时候都需要这些文件中的一个,这取决于用户交互。如果当UI线程请求文件下载时,文件下载还没有完成,我需要显示该特定文件的下载进度。
我已经看到了一些关于显示特定文件下载进度条的答案。但我的要求有些不同。我需要跟踪后台文件下载的进度
当你使用AsyncTask时,你可以选择使用onProgressUpdate(Progress…),在调用publishProgress(Progress…)后在UI线程上调用。
。
private class DownloadFilesTask extends AsyncTask<File, Integer, Long> {
protected Long doInBackground(File... file) {
// This will call onProgressUpdate
publishProgress((int) ((i / (float) count) * 100));
}
// this will be called on the UI thread
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
如果你不使用AsyncTask,你可以创建一个Handler并以这种方式向UI线程发送消息。
但是当你提到文件下载时,需要考虑一些事情(从Android文档):-
- 设备可能没有足够的空间容纳扩展文件,所以你应该在开始下载之前检查并警告用户没有足够的空间。
- 文件下载应该在后台服务中进行,以避免阻塞用户交互并允许用户在下载完成时离开应用程序。
- 在请求和下载过程中可能会发生各种错误,您必须优雅地处理。
- 网络连接在下载过程中可能会发生变化,所以你应该处理这些变化,如果中断,尽可能恢复下载。
- 当下载发生在后台时,你应该提供一个通知来指示下载进度,当它完成时通知用户,并在用户选择时将用户带回到你的应用程序。
幸运的是,上述所有功能都包含在谷歌的一个库中,它提供了一个下载的进度通知(即使你退出了你的应用程序)。您可以使用它,或者根据自己的需要修改源代码。更多信息在这里
http://developer.android.com/google/play/expansion-files.html AboutLibraries
每次下载都应该在自己的线程上运行(如果一个文件更小,一个服务器更快等)。
尝试扩展线程或创建一个由URI或下载的其他标识符参数化的可运行程序。一旦你有了这个,你就可以调用两个线程,它们会一直运行直到完成。如果需要更新UI(进度条),则需要实现一个处理程序,并从线程向处理程序发送消息。例如
在主活动类:
public static final int UPDATE_PROGRESS_BAR =0;
public final Handler uiHander = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case UPDATE_PROGRESS_BAR: // Something like this to handle the case of progress bar update
int updateAmount = msg.obj;
// do something to update prog. bar
break;
然后在线程中发送消息,它需要一个对处理程序
的引用 uiHander.obtainMessage(<activity name>.UPDATE_PROGRESS_BAR,<integer update>).sendToTarget();
这可能是最可移植的方法,因为异步任务的实现已经改变了版本,可能会或可能不会并行执行两个下载(这显然是你想要的)
您可以使用DownloadManager
,但它不会在视图中显示进度。另一种选择是使用ExecutorService
并提交自定义Runnable
任务。将ExecutorService
包装在一个自定义类中,该类维护提交的任务映射。当需要一个文件时,你可以查询这个类任务是否完成,也可以显示运行任务的ListView。