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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11434056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:24:34  来源:igfitidea点击:

How to run a method every X seconds

androidtimernstimer

提问by VansFannel

I'm developing an Android 2.3.3 application and I need to run a method every X seconds.

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

In iOS, I have NSTimer, but in Android I don't know what to use.

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

Someone have recommend me Handler; another recommend me AlarmManagerbut I don't know which method fits better with NSTimer.

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

This is the code I want to implement in Android:

这是我想在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
];

I need something what works like NSTimer.

我需要像NSTimer这样的东西。

What do you recommend me?

你给我推荐什么?

回答by Jug6ernaut

This really depends on how long apart you need to run the function.

这实际上取决于您需要运行该函数多长时间。

If it is => 10 minutes → I would go with Alarm Manager.

如果是 => 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();
}

And then you receive these broadcasts via broadcast receiver. Note that this will need to be registered ether in your application manifest or via context.registerReceiver(receiver,filter);method For more information on Broadcast Receivers please refer to official Docs. Broadcast Receiver.

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

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
         //do stuffs
    }
}

If it is =< 10minutes → I would go with a Handler.

如果是 =< 10 分钟 → 我会和一个 Handler 一起去。

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

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);

回答by Samir Mangroliya

Use Timer for every second...

每秒使用计时器...

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

回答by Umar Ata

You can please try this code to call the handler every 15 seconds via onResume() and stop it when the activity is not visible, via onPause().

您可以尝试使用此代码通过 o​​nResume() 每 15 秒调用一次处理程序,并在活动不可见时通过 onPause() 停止它。

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

回答by wdina

If you are familiar with RxJava, you can use Observable.interval(), which is pretty neat.

如果你熟悉 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
                }
            });

The downside of this is that you have to architect polling your data in a different way. However, there are a lot of benefits to the Reactive Programming way:

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

  1. Instead of controlling your data via a callback, you create a stream of data that you subscribe to. This separates the concern of "polling data" logic and "populating UI with your data" logic so that you do not mix your "data source" code and your UI code.
  2. With RxAndroid, you can handle threads in just 2 lines of code.

    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
    
  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.

请查看 RxJava。它具有很高的学习曲线,但它会使在 Android 中处理异步调用变得更加容易和干净。

回答by Behzad F94

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

回答by Luke

With Kotlin, we can now make a generic function for this!

使用 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)
    }
}

And to use, just do:

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

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

回答by Sam

Here I used a thread in onCreate() an Activity repeatly, timer does not allow everything in some cases Thread is the solution

这里我在 onCreate() 一个 Activity 中重复使用了一个线程,timer 在某些情况下不允许一切都线程是解决方案

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

In case it needed it can be stoped by

如果需要,可以通过以下方式停止

@Override
protected void onDestroy() {
    super.onDestroy();
    Thread.interrupted();
    //t.interrupted();
}

回答by Sepehr

Heremaybe helpful answer for your problem using Rx Java& Rx Android.

这里可能对您使用Rx JavaRx Android 的问题有所帮助。