2013-01-03 62 views
3

我有一個使用Android SDK提供的AsyncTask類的問題。我從我的代碼中開始了一項任務,該任務是定期發送電子郵件(按照指定的時間)。我重新啓動onPostExecute()中的任務。它會定期發送電子郵件,但過了一段時間後,電子郵件會停止。按下後退按鈕是否對它有影響?AsyncTask的使用

我正在通過以下鏈接AsyncTask,發現AsyncTask需要在活動方向更改或焦點不清的情況下刷新。我需要分開處理嗎?每當activity不在焦點或其方向改變時,是否需要刷新context?根據上下文,我正在執行某些數據庫操作。

這裏是我的AsyncTask代碼:

public class SendEmailTask extends AsyncTask<String, Void, String> { 
    private static final String LOG_TAG = "EmailTask"; 
    private static final int MESSAGE_SENT = StringConstants.CONSTANT_YES_FLAG; 
    private Context context; 

    public SendEmailTask(Context context) { 
     this.context = context; 
    } 

    @Override 
    protected String doInBackground(String... time) { 
     // String message = "Message sent at "; 
     try{ 
      //DB operations 
      Validator validator = new Validator(context); 
      int emailInterval = validator.validForSendingEmail(settingsMap); 

      String emailId = settingsMap.get(DBSetting.COLUMN_EMAILID); 
      String emailPwd = settingsMap.get(DBSetting.COLUMN_EMAIL_PWD); 

      if (emailId != null && emailPwd != null && emailInterval > 0) { 
       Thread.sleep((Integer.valueOf(emailInterval) * 60000)); 

       // TODO: formatting of email body 
       DALLog dalLog = DALLog.getDALLogInstance(); 
       dalLog.init(context); 

       GMailSender sender = new GMailSender(emailId, emailPwd); 
       sender.sendMail("Mail From Auto responder", 
         result, emailId, 
         emailId); 

       dalLog.close(); 
      } 
      return null; 
     } 
     catch (NumberFormatException e) { 
      e.printStackTrace(); 
      Log.d(LOG_TAG, e.getMessage()); 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
      Log.d(LOG_TAG, e.getMessage()); 
     } 
     catch (Exception e) { 
      Log.d(LOG_TAG, e.getMessage()); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     //DB operations 
     Validator validator = new Validator(context); 
     int emailInterval = validator.validForSendingEmail(settingsMap); 

     // Start EmailTask thread if not started already 
     SendEmailTask emailTask = new SendEmailTask(context); 
     if (emailTask.getStatus() != AsyncTask.Status.RUNNING) { 
      emailTask.execute(new String[]{}); 
     } 
    } 
} 
+1

是的。 asynctask只存在於啓動它的上下文中。一個活動,很可能。使用服務進行後臺任務。 – njzk2

+3

也應該知道用於asynctask(池)的線程數量有限(默認情況下)。阻止一個不是一個好主意。我會建議使用這個警報管理器。 – njzk2

+0

同意njzk2。另一個說法,條件「if(emailTask​​.getStatus()!= AsyncTask.Status.RUNNING)」是完全沒用的 – gezdy

回答

1

當啓動一個使用活動的背景下一個任務,該任務被在同一生命週期的活動運行。當Activity被銷燬時,其上下文將隨之丟失,如果沒有有效的上下文,任務將失敗。

如果您想要一個在應用程序生命週期中可用的上下文,則應該使用不需要活動Activity的getApplicationContext()(並且不應該用於修改Activity作爲結果)。

不正確的使用情況還可能導致垃圾回收問題 - 對象處於閒置狀態。

正如您在問題的評論部分中提到的那樣,如果您希望能夠在應用程序不在前臺時運行AsyncTask(即在沒有該應用程序的背景中用戶需要的輸入),就是創建一個服務,AsyncTask可以在其中運行。

服務將有自己的上下文,您可以使用,並且您可以將服務綁定到您的活動,如果您想要兩者之間的直接通信。

欲瞭解更多服務信息,請參閱this Android Developer Article其中提供了其使用概述

+0

你的意思是說,當活動被殺死(當活動被推到後面時可能發生),android會自動殺死這個asynctask及其上下文嗎?或者乾脆刪除,即使任務中出現的上下文無效? – Adithya