如何在Android中不使用新类创建简单的计时器?

3

我正在开发一款Android服务,该服务必须在后台运行,并每100秒执行一次函数。以下是源代码(示例):

package com.example

import ....

public class Servizio extends Service {

    public IBinder onBind(Intent intent) {

    }

    public void onCreate() {

    }

    public void onDestroy() {

    //here put the code that stop the timer cycle

    }

    public void onStart(Intent intent, int startid) {

    //i want to begin here the timercycle that each 100 s call myCycle()

    }

    public void myCycle() {

    //code that i can't move on other class!!!

    }

}

我该怎么做?现在这个服务只会执行一次myCycle(),因为我把一个调用放在了onStart()里。

3个回答

7

使用 TimerTimerTask。要每100秒执行您的方法,可以在onStart方法中使用以下内容。请注意,此方法会创建一个新线程。

new Timer().schedule(new TimerTask() {
     @Override
     public void run() {
         myCycle();
     }
}, 0, 100000);

或者,可以像本文所述那样使用android.os.Handler从计时器更新UI。它比计时器更好,因为它在主线程中运行,避免了第二个线程的开销。

private Handler handler = new Handler();
Runnable task = new Runnable() {
    @Override
    public void run() {
        myCycle();
        handler.postDelayed(this, 100000);
    }
};
handler.removeCallbacks(task);
handler.post(task);

我没有“抄袭”你的答案。我已经写好了我的答案。而且你的答案是错误的。 - dogbane
抱歉,我认为由于使用了timertask,出现了问题...Logcat给出了一个停止应用程序的错误:"无法在未调用Looper.prepare()的线程内创建处理程序",与我的代码中的这一行有关:"SurfaceView view = new SurfaceView(this);" 是否还有其他方法? - Lork
@JPM你的答案是正确的,但是它们不起作用...timertask是一个新的类吗? - Lork
@Lork,我已经更新了我的答案,展示了如何使用“Handler”来完成它。看看它是否有效。 - dogbane
从技术上讲,我们的回答都不起作用,因为它们使用了需要更改myCycle()的新类... 但是,如果没有看到myCycle()及其中的内容,我无法确定。 - JPM
很高兴你建议使用Handler.postDelayed。<g> - James Black

2
我通常这样做,如果我理解正确,您想让myCycle每100秒执行一次。
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
    @Override
    public void run() {
        myCycle();
    }
}, 0,100000);

1
当我遇到这个问题时,即定期调用 Web 服务的情况下,我的解决方案如下:
public class MyService extends Service {
    private Handler mHandler = new Handler();
    public static final int ONE_MINUTE = 60000;
    private Runnable periodicTask = new Runnable() {
        public void run() {
            mHandler.postDelayed(periodicTask, 100 * ONE_MINUTE);
            token = retrieveToken();
            callWebService(token);
        }
    };

我提前调用了postDelayed,这样来自webservice的调用延迟不会导致时间偏移。

这两个函数实际上在MyService类中。

更新:

您可以将Runnable传递给postDelayed,如下所示:

http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long)

public final boolean postDelayed (Runnable r, long delayMillis)

Since: API Level 1 Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached.

此外,我的代码由于缺少函数而无法编译,这是OP可以做的示例。


这段代码无法编译。你需要传递 this 而不是 periodicTaskpostDelayed - dogbane
@dogbane - 我拿出了我手头的东西作为演示,它确实编译通过了。我删掉了一些行,但我的periodicTask几乎没有改动,与我目前正在使用的几乎相同。 - James Black
@james-black,抱歉我的错。我没有看到它们是实例变量。 - dogbane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接