在从 Internet 下载数据期间,在 AsyncTask 的 onProgressUpdate 中显示确定的 ProgressBar
Posted
技术标签:
【中文标题】在从 Internet 下载数据期间,在 AsyncTask 的 onProgressUpdate 中显示确定的 ProgressBar【英文标题】:Show determinate ProgressBar in onProgressUpdate of AsyncTask during the time taken to download data from the internet 【发布时间】:2015-11-13 22:32:12 【问题描述】:我正在尝试使用 this library 在 AsyncTask 的 onProgressUpdate()
的活动屏幕上发布进度,该任务用于从 Internet 下载一些数据。他们提供的演示应用程序使用Handler
来演示这一点。我需要在 AsyncTask 中使用它。
以下代码 sn-p 来自他们演示应用程序中的代码。
我的问题是:
onProgressUpdate 得到一个参数Progress... values
,并且
根据documentation,它是“指示的值
进步。” 但是 我不明白这意味着什么,以及如何
使用这个论点。在我看到的例子中,他们正在做
类似:
progressBar.setProgress(Integer.parseInt(values[0]));
为什么他们只使用传递数组中的第一个值 (值[0])?
AsyncTask
如何知道完成需要多长时间
下载操作。我想显示 ProgressBar 的进度
完成下载所用时间的值 0 到 100
手术。
通过progressBarDeterminate.setVisibility(View.VISIBLE)
in
onPreExecute
和做
progressBarDeterminate.setVisibility(View.GONE)
在
onPostExecute
,我们确保它仅在数据出现时显示
正在下载,但我们如何确保它从
开始位置到最终位置
下载数据(当我们不知道它到底有多长时
去下载数据)?
来自演示示例的代码(它使用 Handler,但我需要在 AsyncTask 中执行此操作)
public class MainActivity extends AppCompatActivity
ProgressBarDeterminate progressBarDeterminate;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBarDeterminate = (ProgressBarDeterminate) findViewById(R.id.progressDeterminate);
progressTimer.start();
Thread progressTimer = new Thread(new Runnable()
@Override
public void run()
for(int i = 0; i <= 100; i++)
try
Thread.sleep(30);
catch (InterruptedException e)
e.printStackTrace();
handler.sendMessage(new Message());
);
Handler handler = new Handler(new Handler.Callback()
int progress = 0;
@Override
public boolean handleMessage(Message msg)
progressBarDeterminate.setProgress(progress++);
return false;
);
【问题讨论】:
【参考方案1】:在回答您的第一个问题时,onProgressUpdate
()
采用 varargs 参数。这意味着它可以采用不定数量的指定类型的参数。例如:
public void someMethod(String... args)
//...
可以这样调用,someMethod("Hi!")
或 someMethod("Hi", "there", "welcome", "to", "SO")
。
更多关于 varargs 的信息可以在 here 找到。这些参数的访问方式与访问数组的方式相同。如果那里只有一个参数,那么您可以使用args[0]
。
编辑: 关于您的第二个问题,android 开发人员javadocs 中提供了一个很好的示例:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long>
protected Long doInBackground(URL... urls)
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++)
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
return totalSize;
protected void onProgressUpdate(Integer... progress)
setProgressPercent(progress[0]);
protected void onPostExecute(Long result)
showDialog("Downloaded " + result + " bytes");
也就是说,答案实际上取决于您的情况。假设在上面的示例中您需要下载 10 个 URL。设置for
循环以按顺序下载每个URL
,一旦URL
完成,就会调用publishProgress()
,将当前值转换为百分比数字(i / (float) count) * 100)
。希望这能回答您的问题!
【讨论】:
由于doInBackground
采用可变参数,您可以像对待数组一样对待urls
(即URL[]
对象)。所以,它有一个长度和URL
成员。
在我的应用程序中,在doInBackground
中,数据来自 Web 服务,它的类型很复杂(类似于 JSON),然后我在从 doInBackground
返回之前解析它。所以我不知道如何找出 for 循环应该迭代的迭代次数(即count
变量)。你能推荐点什么吗?
@Solace 恐怕不行,抱歉,我从未在 Android 中使用过 JSON
。
没问题,非常感谢您的回答。我要接受它。我想我要调用publishProgress
三次,在调用 web 服务之前,在数据到来之后,在它被解析之前,在它被解析之后。
@Solace 可以。还要记住,如果您的情况不适合使用百分比样式的更新栏,您可以从publishProgress()
返回任何您喜欢的内容,而不仅仅是Integer
。它可以是 String
用于消息、图像资源值等。以上是关于在从 Internet 下载数据期间,在 AsyncTask 的 onProgressUpdate 中显示确定的 ProgressBar的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch.Net.UnexpectedElasticsearchClientException:在从 ES 获取数据期间
在从 php 会话注销期间取消设置 cookie 有啥意义?
如何让 HSQLDB 在从 .script 文件初始化数据源期间发出错误消息?