I am trying to use this library to publish progress on the Activity screen in the onProgressUpdate()
of an AsyncTask, which is used to download some data from the internet. The demo application they have provided is using Handler
to demonstrate this. I need to use it in an AsyncTask.
Following code snippet is from the code in their demo application.
My questions are:
onProgressUpdate gets an argument Progress... values
, and
according to the documentation, it is "the values indicating
progress." But I don't understand what this means, and how to I
use this argument. In the examples I have seen, they are doing
something like:
progressBar.setProgress(Integer.parseInt(values[0]));
Why are they using only the first value in the passed array (values[0])?
How does the AsyncTask
know how long is it going to take to finish
the download operation. I want to show the ProgressBar progress from
value 0 to 100 during the time spent to finish the download
operation.
By doing progressBarDeterminate.setVisibility(View.VISIBLE)
in
onPreExecute
and doing
progressBarDeterminate.setVisibility(View.GONE)
in
onPostExecute
, we are ensuring that it only shows when the data is
being downloaded, but how to we ensure that it progresses from
starting position to final position during the time it takes to
download the data (when we don't know precisely how long is it
going to take to download the data) ?
CODE FROM DEMO EXAMPLE (It uses Handler, but I need to do this in 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;
}
});
}
In answer to your first question, onProgressUpdate
()
takes a varargs argument. This means that it can take an indefinite number of arguments of the specified type. For example:
public void someMethod(String... args) {
//...
}
Could be called either like this, someMethod("Hi!")
, or this someMethod("Hi", "there", "welcome", "to", "SO")
.
More on varargs can be found here. These arguments are accessed in the same way as you would an array. If there is only one argument there, then you could use args[0]
.
Edit: In regards to your second question, as good an example as any is present in the Android Developers 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");
}
}
Namely, the answer really depends on your circumstances. Say in the above example that you need to download ten URLs. A for
loop is set-up to download each URL
sequentially, and once that URL
has finished, publishProgress()
is called, turning the current value into a percentage figure, (i / (float) count) * 100)
. Hopefully that answers your question!