Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.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
Android-在计时器内重复运行线程_Android_Multithreading_Timer_Repeat - Fatal编程技术网

Android-在计时器内重复运行线程

Android-在计时器内重复运行线程,android,multithreading,timer,repeat,Android,Multithreading,Timer,Repeat,首先,我甚至无法选择要使用的方法,我现在读了几个小时,有人说使用“处理程序”,有人说使用“计时器”。以下是我努力实现的目标: 在首选项中,有一个用于启用/禁用重复作业的设置(复选框)。选中该复选框后,计时器应开始工作,线程应每x秒执行一次。由于复选框未选中,计时器应停止 这是我的密码: 检查是否选中复选框,如果选中,将执行“refreshAllServers”void,该操作将使用计时器执行作业 boolean CheckboxPreference = prefs.getBoolean("che

首先,我甚至无法选择要使用的方法,我现在读了几个小时,有人说使用“处理程序”,有人说使用“计时器”。以下是我努力实现的目标:

在首选项中,有一个用于启用/禁用重复作业的设置(复选框)。选中该复选框后,计时器应开始工作,线程应每x秒执行一次。由于复选框未选中,计时器应停止

这是我的密码:

检查是否选中复选框,如果选中,将执行“refreshAllServers”void,该操作将使用计时器执行作业

boolean CheckboxPreference = prefs.getBoolean("checkboxPref", true);
                if(CheckboxPreference == true) {
                    Main main = new Main();
                    main.refreshAllServers("start");
                } else {
                    Main main = new Main();
                    main.refreshAllServers("stop");
                }
执行计时器作业的refreshAllServers无效:

public void refreshAllServers(String start) {

    if(start == "start") {

        // Start the timer which will repeatingly execute the thread

    } else {

        // stop the timer

            }
下面是我执行线程的方式:(在没有计时器的情况下运行良好)

我试过什么

我尝试了从谷歌上看到的任何例子(处理器、计时器),它们都不起作用,我设法启动了计时器一次,但停止了它就不起作用了。 我在研究中看到的最简单易懂的代码是:

new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        5000 
);

我想使用AlarmManager

如果复选框为待命方法,其中

AlarmManager alarmManager = (AlarmManager)SecureDocApplication.getContext()
    .getSystemService(Context.ALARM_SERVICE);
PendingIntent myService = PendingIntent.getService(context, 0, 
                new Intent(context, MyService.class), 0);

long triggerAtTime = 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, 5000 /* 5 sec*/, 
                myService);
如果复选框处于关闭状态,则取消报警管理器

alarmManager.cancel(myService);

使用倒计时。它的工作方式是在计时器的每个滴答声上调用一个方法,在计时器结束时调用另一个方法。在这一点上,如果需要,您可以重新启动。此外,我认为您可能应该启动异步任务,而不是线程。请不要尝试在Android中管理自己的线程。尝试如下。它跑起来像个钟

 CountDownTimer myCountdownTimer =    new CountDownTimer(30000, 1000) {

 public void onTick(long millisUntilFinished) {
     mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     // Kick off your AsyncTask here.
 }

 public void onFinish() {
     mTextField.setText("done!");
     // the 30 seconds is up now so do make any checks you need here.
 }
 }.start();

只需使用下面的代码片段

private final Handler handler = new Handler();
private Runnable runnable = new Runnable() {
    public void run() {
         //
         // Do the stuff
         //

         handler.postDelayed(this, 1000);
    }
};
runnable.run();
要阻止它,请使用

handler.removeCallbacks(runnable);

应该可以做到这一点。

多亏了大家,我用定时器解决了这个问题

timer = new Timer();
timer.scheduleAtFixedRate(
    new java.util.TimerTask() {
        @Override
        public void run() {
            for (int i = 0; i < server_amount; i++) {

                servers[i] = "Updating...";
                handler.sendEmptyMessage(0);
                new MyThread(i).start();
            }
        }
    },
2000, 5000);
timer=新定时器();
timer.scheduleAtFixedRate(
新的java.util.TimerTask(){
@凌驾
公开募捐{
对于(int i=0;i
“[ScheduledThreadPoolExecutor]类在需要多个工作线程时,或者在需要ThreadPoolExecutor(该类扩展)的额外灵活性或功能时,优于Timer。”

它并不比处理程序多很多,但可以选择每隔一段时间运行一次(反之,每次计算完成后都会有一个延迟)


看看答案是否有帮助。这不会重复做这件事。有一次,它停了!是的,它不会无限期地运行。如果你想无限期地运行它,你可以考虑一个后台服务。另一方面,如果条件合适,没有什么可以阻止您重新启动倒计时计时器,或者设置更长的持续时间。请使用类成员变量作为alarm manager的实例。当复选框处于调用状态时,使用该代码的方法。关闭报警管理器的方法。当用户浏览活动时,然后在继承的应用程序类中,就会发生这种情况。如果用户可以退出应用程序,但仍需要在服务中运行。您的解决方案也很有效,因为我找到了其他解决方案。我认为这是最好的解决方案。如果用户希望通过连接到internet来完成某项任务,该怎么办?应用上述方法将使处理程序和runnable在UI线程上运行,这将阻止执行任何网络操作。你需要在那里实现线程。这很聪明,我已经在我的程序的一部分中使用了它,它工作得很好。但后来我尝试在程序中类似服务的部分使用is,该部分没有任何UI,这导致“java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序”,这很公平。因此,这是一种进行计时器式处理的简洁方法,但不适用于应用程序中没有UI的部分。请说明此解决方案相对于其他解决方案的优势。我没有看到。没有好处,我只是发现Coders Paradise的答案在我工作后也起了作用。
timer = new Timer();
timer.scheduleAtFixedRate(
    new java.util.TimerTask() {
        @Override
        public void run() {
            for (int i = 0; i < server_amount; i++) {

                servers[i] = "Updating...";
                handler.sendEmptyMessage(0);
                new MyThread(i).start();
            }
        }
    },
2000, 5000);
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


...


final int THREAD_POOL_SIZE = 10;
final int START_DELAY = 0;
final int TIME_PERIOD = 5;
final TimeUnit TIME_UNIT = TimeUnit.SECONDS;

ScheduledThreadPoolExecutor pool;

Runnable myPeriodicThread = new Runnable() {
    @Override
    public void run() {
        refreshAllServers();
    }
};


public void startTimer(){

    pool.scheduleAtFixedRate(myPeriodicThread,
            START_DELAY,
            TIME_PERIOD,
            TIME_UNIT);

}

public void stopTimer(){

    pool.shutdownNow();

}