如何每X秒运行一次方法

时间:2012-07-11 13:45:52

标签: 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
];

我需要像NSTimer那样的东西。

你推荐我什么?

9 个答案:

答案 0 :(得分:146)

这实际上取决于你需要多长时间才能运行这个功能。

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

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

public class MyReceiver extends BroadcastReceiver{

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

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

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

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

答案 1 :(得分:85)

每秒使用一次计时器......

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

答案 2 :(得分:46)

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

    Handler h = 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

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

                h.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() {
        h.removeCallbacks(runnable); //stop handler when activity not visible
        super.onPause();
    }

答案 3 :(得分:12)

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

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

  1. 您可以创建自己订阅的数据流,而不是通过回调控制数据。这分离了对轮询数据的关注&#34;逻辑和&#34;用您的数据填充UI&#34;逻辑,这样你就不会混淆你的数据源&#34;代码和您的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
    
  3. 请查看RxJava。它具有很高的学习曲线,但它将使处理Android中的异步调用变得更加容易和清晰。

答案 4 :(得分:2)

这里我在onCreate()和一个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();
}

答案 5 :(得分:2)

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

答案 6 :(得分:0)

借助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()
}

答案 7 :(得分:0)

Here对于使用 Rx Java Rx Android 的问题可能是有用的答案。

答案 8 :(得分:0)

我这样做并且效果很好(代码是用 Kotlin 编写的):

private lateinit var runnable: Runnable

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

private val repeatPeriod: Long = 10000

然后从你的函数内部重新初始化 runnable

runnable = Runnable {

        // Your code goes here

        handler.postDelayed(runnable, repeatPeriod)

    }

    handler.postDelayed(runnable, repeatPeriod)

}

请注意,如果您没有 postDelay 两倍于 handler,则循环不会是无限的!