How to run a method every X seconds

2019-01-02 22:41发布

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

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

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

This is the code I want to implement in 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.

What do you recommend me?

6条回答
贪生不怕死
2楼-- · 2019-01-02 23:16

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

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
    

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

查看更多
成全新的幸福
3楼-- · 2019-01-02 23:21

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

     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();
}
查看更多
孤傲高冷的网名
4楼-- · 2019-01-02 23:22
    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();
查看更多
Rolldiameter
5楼-- · 2019-01-02 23:23

Use Timer for every second...

new Timer().scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {}
            }, 0, 1000);//put here time 1000 milliseconds=1 second
查看更多
▲ chillily
6楼-- · 2019-01-02 23:31

try this code to call handler every 15 seconds and stop it when activity not visible

    Handler h = new Handler();
    int delay = 15*1000; //1 second=1000 milisecond, 15*1000=15seconds
    Runnable runnable;

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

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

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

        super.onResume();
    }

    @Override
    protected void onPause() {
        h.removeCallbacks(runnable); //stop handler when activity not visible
        super.onPause();
    }
查看更多
来,给爷笑一个
7楼-- · 2019-01-02 23:32

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

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

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

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.

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

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);
查看更多
登录 后发表回答