2012-02-10 4 views
1

Я пытаюсь загрузить файл с URL-адреса. Если загрузка не удалась (независимо от причины), я хочу, чтобы приложение повторилось через час.Как запустить CountDownTimer, когда меня нет в основной теме

Поскольку загрузка находится в ее собственном потоке (а не в главном потоке), я не могу запустить новый 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 
    } 

ответ

1

Вы можете создать таймер, который будет начать загрузку на вашем UI потоке. В классе 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(); 
} 

В вашем Downloader onPostExecute(), начать новый таймер, который истекает в течение 1 часа.

protected void onPostExecute(File file) 
    { 
     if (!isVideoLoaded) 
      startOneHourTimer(); 
     else 
      //Call your normal UI code here 
    } 
0

Измените ваш onPostExecute так, чтобы он перезванивает к основной деятельности, чтобы показать, что загрузка не удалась (должны быть в состоянии добраться до него MyMainActivity.this.someMethod().) Основной вид деятельности может затем сделать новый AsyncTask (вы можете повторное использование старого) и означает, что он должен задерживать запуск.

Один из вариантов для этого - добавить конструктор к вашей AsyncTask, чтобы вы могли передать ему параметр задержки, тогда ваш AsyncTask может использовать параметр задержки как часть метода doInBackground.

Внутри doInBackground просто ждать с Thread.sleep()