Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AsyncTask在Android中无法正确重新启动_Java_Android_Multithreading_Android Asynctask - Fatal编程技术网

Java AsyncTask在Android中无法正确重新启动

Java AsyncTask在Android中无法正确重新启动,java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我正在开发一个Android应用程序,我需要根据共享首选项中的变量不时显示提醒对话框。如果用户不想看到提醒消息,他也可以在“我的首选项”活动中禁用此选项。我使用AsyncTask类不时向用户显示提醒消息。用户可以随时按options按钮转到PreferenceActivity以启用/禁用提醒选项,并设置提醒和返回活动之间的暂停时间值。所以我检查onResume方法中的所有值。如果用户不想看到提醒消息,我需要完成当前的异步工作任务,或者如果用户在提醒之间更改了值,我需要使用新的暂停值重新启动当前的

我正在开发一个Android应用程序,我需要根据共享首选项中的变量不时显示提醒对话框。如果用户不想看到提醒消息,他也可以在“我的首选项”活动中禁用此选项。我使用AsyncTask类不时向用户显示提醒消息。用户可以随时按options按钮转到PreferenceActivity以启用/禁用提醒选项,并设置提醒和返回活动之间的暂停时间值。所以我检查onResume方法中的所有值。如果用户不想看到提醒消息,我需要完成当前的异步工作任务,或者如果用户在提醒之间更改了值,我需要使用新的暂停值重新启动当前的异步。但我看到我的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;
    }
 }

有人能帮我解决我的问题吗?

这通常是个糟糕的解决方案<代码>异步任务在处理配置更改方面不是很好

根据延迟的时间长短,您可以使用
AlarmManager.setInexactRepeating
来显示这些对话框。您可以使用
pendingent.getService
pendingent.getBroadcast
创建新的
pendingent
,具体取决于您希望实现显示对话框的方式—(从
Service
您将只能显示类似系统的对话框)

并注册一个BroadcastReceiver,它将处理显示对话框的操作


如果延迟时间不长,您可以创建一个自定义的
ThreadPoolExecutor
,它将执行您想要的操作。

我认为不应该使用AsyncTask来实现这一点<代码>线程。睡眠(mRemindTime)也很难看!如果你需要一个计时器,那就用它。

这真的不是一个很好的方法。发生“不可预测行为”的原因是,即使在
活动停止后,任务仍在运行。在您的
onResume
中调用
cancel
,不仅为时已晚,实际上根本没有做任何事情

查看
处理程序.postDelayed
。你想要这样的东西:

在您的
onCreate中

hdlr = new Handler();
reminder = new Runnable() { public void run() { showReminder(); } }
编辑以将必要的第二个参数添加到postDelayed

。。。在您的
简历中

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()”。

在您的else-if语句中,您正在创建一个新任务并执行它,我认为这不会停止旧任务。尝试取消任务,然后检查是否已取消,如果已取消,则使用不同参数启动同一任务,否则再次尝试取消并检查。不要每次都创建新任务。谢谢!我现在就试试这个。这里三分之三的解决方案告诉你不要“尝试这个”。真的,杜德:你做错了。好吧,但我在处理这个问题时太糊涂了,所以我尝试了所有的解决方案。)CountDownTime能在我的活动运行时以一定的时间间隔做一些工作吗?你是说这个
onTick(long millisuntilly)
?谢谢!我会试试这个解决方案。报警管理器是一个很好的解决方案,如果它很重的话。AsyncTasks就是在ThreadPoolExecutor上运行的任务。使用自定义ThreadPoolExecutor重新实现AsyncTasks不是一个很好的解决方案。@G.Blake Meike是的,你是对的。但是你对发生的事情有了更多的控制权。我还可以假设使用
Handler
postDelayed
发布相同的
Runnable
,尽管我不确定它将如何处理配置更改。在run()方法中,我需要在initrementer()之前创建类似Thread.SLeep(val)的东西?我说得对吗?谢谢!你的解决方案对我有效。我只添加了hdlr.postDelayed(提醒,时间);showReminder()之后的run()方法;打电话.@bukka.wh是的!感谢您指出我的代码遗漏了那个基本参数。编辑。
hdlr.removeCallbacks(reminder);
public Void doInBackground(Long... params){
     mRemindTime = params[0];
     while (!isCancelled()){
         try{
             Thread.sleep(mRemindTime);
             if(!isCancelled())
                 publishProgress();
         }
        catch (Exception e){
            e.printStackTrace();
        }
     }
     return null;
 }