3

AsyncTaskAndroid sdk が提供するクラスの使用について質問があります。私は自分のコードで、定期的に(指定された時間に従って)電子メールを送信する作業を行うアクティビティからタスクを開始しています。でタスクを再開しますonPostExecute()。定期的にメールを送信しますが、しばらくするとメールが送信されなくなります。戻るボタンを押すと何か影響がありますか?

AsyncTaskの次のリンクを調べていたところAsyncTask、アクティビティの向きが変わった後、または焦点が合っていないときに更新する必要があることがわかりました。これを個別に処理する必要がありますか? 焦点が合っていないか、向きが変わるたびcontextに更新する必要がありますか? activityコンテキストに基づいて実行している特定の DB 操作があります。

これが私の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

アクティビティのコンテキストを使用するタスクを起動すると、そのタスクはアクティビティと同じライフサイクルで実行されます。アクティビティが破棄されると、そのコンテキストは失われます。有効なコンテキストがないと、タスクは失敗します。

アプリケーションの存続期間中利用可能なコンテキストがgetApplicationContext() 必要な場合は、アクティブなアクティビティを必要としないコンテキストを使用する必要があります(結果としてアクティビティを変更するために使用しないでください)。

誤った使用法は、ガベージコレクションの問題を引き起こす可能性もあります-オブジェクトが浮かんでいるままになります。

質問のコメントセクションで述べたように、アプリケーションがフォアグラウンドにないときに(つまり、ユーザーの入力を必要とせずにバックグラウンドで)AsyncTaskを実行できるようにする場合は、先に進むための最良の方法です。 、AsyncTaskが実行できるサービスを作成することです。

サービスには、使用できる独自のコンテキストがあり、2つの間で直接通信する場合は、サービスをアクティビティにバインドできます。

サービスの詳細については、その使用の概要を提供するこのAndroidデベロッパーの記事を参照してください

于 2013-01-03T11:22:09.410 に答える