我正在尝试从网址下载文件。如果下载失败(无论原因)我希望应用程序在一小时后重试。
由于下载是在自己的线程(不是主线程),我似乎无法启动新的CountDownTimer。
我不想阻止下载线程,所以我正在尝试使用CountDownTimer。
还有其他办法吗?
提前致谢!
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
}
答案 0 :(得分:1)
您可以创建一个可在UI线程上开始下载的Timer。 在UI类中,使用此函数
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();
}
在你的下载器onPostExecute()中, 启动一个将在1小时后到期的新计时器。
protected void onPostExecute(File file)
{
if (!isVideoLoaded)
startOneHourTimer();
else
//Call your normal UI code here
}
答案 1 :(得分:0)
更改您的onPostExecute
,以便回拨主活动以表示下载失败(应该能够通过MyMainActivity.this.someMethod()
访问它。)然后,主要活动可以重新启动AsyncTask(你不能重用旧的)并表示它应该延迟启动。
执行此操作的一个选项是向AsyncTask添加构造函数,以便可以向其传递延迟参数,然后AsyncTask可以将delay参数用作doInBackground
方法的一部分。
在doInBackground
内,只需等待Thread.sleep()