簡體   English   中英

AsyncTask無法在Android中正確重啟

[英]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.getServicePendingIntent.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM