如何每隔 X 秒运行一个方法

我正在开发一个 Android2.3.3应用程序,我需要每个 X 秒运行一个方法。

在 iOS 系统中,我有 NSTimer,但在 Android 系统中,我不知道该用什么。

有人推荐我使用 管理员,也有人推荐我使用 警报管理器,但是我不知道哪种方法更适合使用 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
];

我需要像 NSTimer这样的东西。

你推荐我什么?

213536 次浏览

每秒使用计时器..。

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

您将使用的解决方案实际上取决于在每次执行函数之间需要等待多长时间。

如果你等待超过10分钟,我建议使用 AlarmManager

// 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 // PendingIntent 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();
}

一旦你广播了上面的 Intent,你可以通过实现一个 BroadcastReceiver来接收你的 Intent。请注意,这将需要在您的应用程序清单中或通过 context.registerReceiver(receiver, intentFilter);方法注册。关于 BroadcastReceiver的更多信息请参考官方文件。.

public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
System.out.println("MyReceiver: here!") // Do your work here
}
}

如果你正在等待短于10分钟,那么我会建议使用 Handler

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


handler.postDelayed(new Runnable() {
public void run() {
System.out.println("myHandler: here!"); // Do your work here
handler.postDelayed(this, delay);
}
}, delay);

您可以尝试通过 onResume ()每15秒调用处理程序一次,并在活动不可见时通过 onPuse ()停止它。

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();
}

如果您熟悉 RxJava,那么可以使用 Observer able.gap () ,这非常简洁。

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
}
});

这样做的缺点是,您必须以不同的方式构建轮询数据的架构。不过,这种响应式编程也有很多好处:

  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
    

Please check out RxJava. It has a high learning curve but it will make handling asynchronous calls in Android so much easier and cleaner.

这里我在 onCreate () an Activity 中重复使用了一个线程,在某些情况下计时器不允许所有的线程是解决方案

     Thread t = new Thread() {
@Override
public void run() {
while (!isInterrupted()) {
try {
Thread.sleep(10000);  //1000ms = 1 sec
runOnUiThread(new Runnable() {
@Override
public void run() {


SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("chat_list", "");
GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class);
String sam = "";


ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData());
listview.setAdapter(adapter);
// listview.setStackFromBottom(true);
//  Util.showMessage(Chat.this,"Merhabalar");
}
});


} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};


t.start();

如果需要,它可以被阻止

@Override
protected void onDestroy() {
super.onDestroy();
Thread.interrupted();
//t.interrupted();
}
    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();

有了 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)
}
}

要使用,只要做:

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
myRepeatedFunction()
}

我这样做,它工作得很好(代码是用 科特林编写的) :

private lateinit var runnable: Runnable


private var handler = Handler(Looper.getMainLooper())


private val repeatPeriod: Long = 10000

然后从函数内部重新启动可运行程序

runnable = Runnable {


// Your code goes here


handler.postDelayed(runnable, repeatPeriod)


}


handler.postDelayed(runnable, repeatPeriod)

注意,如果你没有 延迟的两倍的 联络人,循环将不会是无限的!

科特林中,你可以这样使用 Runnable:

private lateinit var runnable: Runnable
private var handler = Handler(Looper.getMainLooper())
private val interval: Long = 1000
private var isRunning = false
val runnable = object : Runnable {
override fun run() {
// Do something every second
function()
// Call your runnable again after interval
handler?.postDelayed(runnable(this, interval))
}
}
    

// Call your function once
if (!isRunning) {
handler?.postDelayed(runnable, interval)
isRunning = true
}


// Remove your repeatedly called function
if (isRunning) {
handler?.removeCallbacks(runnable)
isRunning = false
}