3

我对使用AsyncTaskAndroid sdk 提供的类有疑问。我正在我的代码中从活动中开始一项任务,该活动的工作是定期发送电子邮件(根据指定的时间)。我在中重新启动任务onPostExecute()。它确实会定期发送电子邮件,但一段时间后电子邮件停止发送。按后退键有影响吗?

我正在浏览AsyncTask上的以下链接,发现AsyncTask在活动的方向改变或失焦后需要刷新。我需要单独处理吗?context每次activity失焦或其方向发生变化时,我是否需要刷新?我正在根据上下文进行某些数据库操作。

这是我的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[]{});
        }
    }
}
4

1 回答 1

1

当您启动使用 Activity 上下文的任务时,该任务将在与 Activity 相同的生命周期中运行。当 Activity 被销毁时,它的上下文将随之丢失,如果没有有效的上下文,任务将失败。

如果您想要一个在应用程序的生命周期内可用的上下文,您应该使用getApplicationContext() 不需要活动活动的上下文(因此不应该用于修改活动)。

不正确的使用也可能导致垃圾收集问题 - 对象漂浮在周围。

正如您问题的评论部分中提到的那样,如果您希望能够在应用程序不在前台时运行 AsyncTask(即,在不需要用户输入的情况下在后台运行),那么最好的前进方式, 是创建一个AsyncTask 可以在其中运行的服务。

Service 将有自己的上下文供您使用,如果您希望两者之间直接通信,您可以将 Service 绑定到您的 Activity。

有关服务的更多信息,请参阅这篇 Android 开发者文章,其中概述了它们的使用

于 2013-01-03T11:22:09.410 回答