[英]AsyncTask does not correctly restart in Android
我正在開發一個Android應用程序,我需要根據共享首選項中的變量不時顯示提醒對話框。 如果用戶不想看到提醒消息,他也可以在我的PreferenceActivity中禁用此選項。 我正在使用AsyncTask類向用戶不時顯示提醒消息。 用戶可以隨時按選項按鈕轉到PreferenceActivity以啟用/禁用提醒選項,並設置提醒之間的暫停時間值,然后返回活動狀態。 所以我正在檢查onResume方法中的所有值。 而且,如果用戶不想看到提醒消息,則需要完成當前的AsyncTask工作,或者如果用戶在兩次提醒之間更改了值,則需要使用新的暫停值重新啟動當前的AsyncTack。 但是我看到我的AsyncTack的行為無法預測:有時它停止,有時不運行,並繼續工作並顯示消息)))),有時它可以工作,有時-不能))))。 這是一段代碼:
這是我的AsyncTack類
private class ReadReminderTask extends AsyncTask<Long, Void, Void> {
private long mRemindTime;
private volatile boolean running = true;
public ReadReminderTask(){
}
@Override
public Void doInBackground(Long... params){
mRemindTime = params[0];
while (running){
try{
Thread.sleep(mRemindTime);
publishProgress();
}
catch (Exception e){
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Void... progress) {
super.onProgressUpdate(progress);
// showReminder is a method where I show remind message
showReminder();
}
@Override
protected void onCancelled() {
running = false;
}
}
這是我的Activity的onResume方法,需要顯示提醒消息:
if(!settings.getBoolean("needToRemind", false)) {
mReadReminderTask.cancel(true);
} else if(settings.getBoolean("needToRemind", false)) {
mReadReminderTask = new ReadReminderTask();
mReadReminderTask.execute(settings.getLong("timeRemind", 1));
}
誰能幫我解決我的問題?
確實,這並不是一個好方法。 之所以發生“無法預料的行為”,是因為即使您的“ Activity
已停止,您仍使任務運行。 在您的onResume
cancel
的調用不僅為時已晚,而且實際上根本沒有做任何事情。
看看Handler.postDelayed
。 您想要這樣的東西:
在你的onCreate
hdlr = new Handler();
reminder = new Runnable() { public void run() { showReminder(); } }
編輯以將基本第二參數添加到postDelayed
...在您的onResume
:
hdlr.postDelayed(reminder, mRemindTime);
...並且在您的onPause
:
hdlr.removeCallbacks(reminder);
請注意,AsyncTask.cancel()並不會真正取消正在運行的任務。 相反,它僅設置一個標志來通知已請求取消。 是否以及何時考慮此標志取決於AsyncTask的實現。
Thread.sleep返回后,您當前的代碼不檢查取消。 正確的實現將是這樣的:
public Void doInBackground(Long... params){
mRemindTime = params[0];
while (!isCancelled()){
try{
Thread.sleep(mRemindTime);
if(!isCancelled())
publishProgress();
}
catch (Exception e){
e.printStackTrace();
}
}
return null;
}
另外,不需要asynctask中的屬性“ running”和onCancelled()方法。 您可以改用方法“ isCancelled()”。
通常這是一個糟糕的解決方案。 AsyncTasks
不能很好地處理配置更改。
根據延遲的時間長短,可以使用AlarmManager.setInexactRepeating
來顯示這些對話框。 您可以根據要實現顯示對話框的方式,使用PendingIntent.getService
或PendingIntent.getBroadcast
創建新的PendingIntent
(從Service
只能顯示類似於系統的對話框)。
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intentStart = new Intent();
intentStart.setAction(SHOW_DIALOG_ACTION);
PendingIntent pendingIntentStart = PendingIntent.getBroadcast(context, 0, intentStart, 0);
並注冊一個BroadcastReceiver,它將處理顯示對話框。
如果延遲時間不長,則可以創建一個自定義ThreadPoolExecutor
,它將執行您想要的操作。
我不認為AsyncTask應該用於此。 Thread.sleep(mRemindTime)
也很丑! 如果需要計時器,請使用CountDownTimer 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.