Reputation: 105
I am trying to download a file from a URL. If the download fails (regardless of the reason) I want the application to retry an hour later.
Since the download is in it's own thread (not the main thread), I can't seem to start a new CountDownTimer.
I don't want to block the download thread so I'm trying to use the CountDownTimer.
Is there another way to do this?
Thanks in advance!
private class Downloader extends AsyncTask<Object, Void, File>
{
@Override
protected File doInBackground(Object... params)
{
Context context = (Context) params[0];
String strUrl = (String) params[1];
String strFileName = (String) params[2];
return download(context, strUrl, strFileName);
}
/**
* Downloads files in a separate thread. Adds notification of download to status bar.
*/
public File download(final Context context, final String url, final String fileName)
{
boolean isVideoLoaded=false;
try
{
URL urlObj = new URL(url);
URLConnection con = urlObj.openConnection();
BufferedInputStream bis = new BufferedInputStream(con.getInputStream(), BUFFER_SIZE);
FileOutputStream fos = new FileOutputStream(retFile);
byte[] bArray = new byte[BUFFER_SIZE];
int current = 0;
int read = 0;
while(current != -1)
{
fos.write(bArray,0,current);
current = bis.read(bArray, 0, BUFFER_SIZE);
read = read + current;
}
fos.close();
bis.close();
isVideoLoaded = true;
strFileName = retFile.getAbsolutePath();
}
catch(Exception ioe)
{
Log.d("Downloader.download", "Error: " + ioe.toString(), ioe);
}
}
if (!isVideoLoaded) // if video is still not loaded
{
// sleep then try again
new CountDownTimer(15000, 2000)
{
public void onFinish()
{
Downloader dh = new Downloader();
Object params[] = new Object[3];
params[0] = context;
params[1] = url;
params[2] = fileName;*/
dh.execute(params);
}
@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
}.start();
}
return retFile;
}
protected void onPostExecute(File file) {
// display downloaded file
}
Upvotes: 2
Views: 1887
Reputation: 34
You can create a Timer that will start a download on your UI thread. In your UI class, use this function
private StartOneHourTimer()
{
new CountDownTimer(10000 * 3600, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
m_downloader = new Downloader(..);
m_downloader.execute(..);
}
}.start();
}
In your Downloader onPostExecute(), start a new Timer that will expire in 1 hour.
protected void onPostExecute(File file)
{
if (!isVideoLoaded)
startOneHourTimer();
else
//Call your normal UI code here
}
Upvotes: 1
Reputation: 6607
Change your onPostExecute
so that it calls back out to the main activity to signify that the download failed (should be able to get to it by MyMainActivity.this.someMethod()
.) The main activity can then make a new AsyncTask (you can't reuse the old one) and signify that it should delay start.
One option for doing this is to add a constructor to your AsyncTask so you can pass a delay parameter to it, then your AsyncTask can use the delay parameter as part of the doInBackground
method.
Inside doInBackground
simply wait with a Thread.sleep()
Upvotes: 0