如何每X秒运行一次方法

Van*_*nel 102 android timer nstimer

我正在开发一个Android 2.3.3应用程序,我需要每隔X秒运行一个方法.

在iOS中,我有NSTimer,但在Android中我不知道该使用什么.

有人推荐我Handler ; 另一个推荐我AlarmManager,但我不知道哪种方法更适合NSTimer.

这是我想在Android中实现的代码:

timer2 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f)
    target:self
    selector:@selector(loopTask)
    userInfo:nil
    repeats:YES
];

timer1 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f)
    target:self
    selector:@selector(isFree)
    userInfo:nil
    repeats:YES
];
Run Code Online (Sandbox Code Playgroud)

我需要一些像NSTimer一样的东西.

你推荐我什么?

Jug*_*aut 153

这实际上取决于运行该功能需要多长时间.

如果=> 10分钟→我会选择报警管理器.

// Some time when you want to run
Date when = new Date(System.currentTimeMillis());    

try{
   Intent someIntent = new Intent(someContext,MyReceiver.class); // intent to be launched

   // note this could be getActivity if you want to launch an activity
   PendingIntent pendingIntent = PendingIntent.getBroadcast(
        context, 
        0, // id, optional
        someIntent, // intent to launch
        PendingIntent.FLAG_CANCEL_CURRENT); // PendintIntent flag

   AlarmManager alarms = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE);

   alarms.setRepeating(AlarmManager.RTC_WAKEUP,
        when.getTime(),
        AlarmManager.INTERVAL_FIFTEEN_MINUTES,
        pendingIntent); 

}catch(Exception e){
   e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

然后你通过广播接收器接收这些广播.请注意,这需要在应用程序清单中或通过context.registerReceiver(receiver,filter);方法注册ether.有关广播接收器的更多信息,请参阅官方文档.广播接收器.

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
         //do stuffs
    }
}
Run Code Online (Sandbox Code Playgroud)

如果= <10分钟→我会使用处理程序.

Handler handler = new Handler();
int delay = 1000; //milliseconds

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);
Run Code Online (Sandbox Code Playgroud)

  • @SunamAndréForsberg在[AlarmManager docs](http://developer.android.com/reference/android/app/AlarmManager.html)中指出Handler是用于短标记的优先和更有效的方法:"注意: Alarm Manager适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行.对于正常的计时操作(刻度,超时等),使用Handler更容易,更有效". (9认同)
  • 效率,在AlarmManager文档中,它声明它不应该用于任何小间隔重复任务. (6认同)
  • 为什么不同的建议取决于时间延迟? (2认同)
  • 来自runnable的@ahmadalibaloch你可以做```h`removeCallbacks(this);```,否则你需要保持对runnable的引用才能删除它.如果需要第二个,那么此处发布的方法可能不是您的最佳选择. (2认同)
  • 这种不断递归的形式最终不会导致堆栈溢出吗? (2认同)

Sam*_*iya 92

每秒使用Timer ......

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //your method
    }
}, 0, 1000);//put here time 1000 milliseconds=1 second
Run Code Online (Sandbox Code Playgroud)

  • 不要使用计时器(http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/),请使用Handler或ScheduledThreadPoolExecutor。 (2认同)

Uma*_*Ata 54

尝试此代码每15秒调用一次处理程序,并在活动不可见时停止它

Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000; //Delay for 15 seconds.  One second = 1000 milliseconds.


@Override
protected void onResume() {
   //start handler as activity become visible

    handler.postDelayed( runnable = new Runnable() {
        public void run() {
            //do something

            handler.postDelayed(runnable, delay);
        }
    }, delay);

    super.onResume();
}

// If onPause() is not included the threads will double up when you 
// reload the activity 

@Override
protected void onPause() {
    handler.removeCallbacks(runnable); //stop handler when activity not visible
    super.onPause();
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是我想要的.完善. (4认同)
  • 这是完美的答案! (3认同)

小智 15

如果您熟悉RxJava,可以使用Observable.interval(),它非常整洁.

Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(new Function<Long, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(@NonNull Long aLong) throws Exception {
                    return getDataObservable(); //Where you pull your data
                }
            });
Run Code Online (Sandbox Code Playgroud)

这样做的缺点是您必须以不同的方式构建轮询数据.但是,Reactive Programming方式有很多好处:

  1. 您可以创建您订阅的数据流,而不是通过回调控制数据.这就分散了"轮询数据"逻辑和"用数据填充UI"逻辑的关注,这样就不会混淆"数据源"代码和UI代码.
  2. 使用RxAndroid,您只需2行代码即可处理线程.

    Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(...) // polling data code
          .subscribeOn(Schedulers.newThread()) // poll data on a background thread
          .observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread
          .subscribe(...); // your UI code
    
    Run Code Online (Sandbox Code Playgroud)

请查看RxJava.它具有很高的学习曲线,但它将使处理Android中的异步调用变得更加容易和清晰.


Luk*_*uke 8

使用 Kotlin,我们现在可以为此创建一个通用函数!

object RepeatHelper {
    fun repeatDelayed(delay: Long, todo: () -> Unit) {
        val handler = Handler()
        handler.postDelayed(object : Runnable {
            override fun run() {
                todo()
                handler.postDelayed(this, delay)
            }
        }, delay)
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用,只需执行以下操作:

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
    myRepeatedFunction()
}
Run Code Online (Sandbox Code Playgroud)


小智 5

    new CountDownTimer(120000, 1000) {

        public void onTick(long millisUntilFinished) {
            txtcounter.setText(" " + millisUntilFinished / 1000);

        }

        public void onFinish() {

            txtcounter.setText(" TimeOut  ");
            Main2Activity.ShowPayment = false;
            EventBus.getDefault().post("go-main");

        }

    }.start();
Run Code Online (Sandbox Code Playgroud)

  • 不要发布代码只回答。请[编辑]您的答案并添加一些解释。 (4认同)