Android重复任务的处理程序-它们会重叠吗?定时器任务VS处理程序VS闹钟管理器

11

我想创建一个Android应用程序,每10分钟重复运行某些进程。据我发现,与定时器或调度相比,Handlers 更可靠。因此,我打算使用下面给出的代码来开发我的应用程序。

我有点担心下面的代码每次启动应用程序都会创建单独的Handler,并使它们并行运行,可能是因为我在onCreate中创建了Handler

那么,保持仅有一个Handler在后台运行的最佳方法是什么?

private Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    handler = new Handler(); // new handler
    handler.postDelayed(runnable, 1000*60*10); // 10 mins int.
    setContentView(R.layout.activity_pro__sms);
} 

private Runnable runnable = new Runnable() {
    @Override
    public void run() {
        /* my set of codes for repeated work */
        foobar();
        handler.postDelayed(this, 1000*60*10); // reschedule the handler
    }
};

只是好奇:你的“重复工作”的上下文是什么?或者更好地说,这是什么样的应用程序?认为用户会在一次使用中积极使用您的应用程序超过10分钟可能是一个非常慷慨的假设(除非它像游戏一样,因此我的问题)。在您的应用程序不在前台时使用Handler可能不是正确的操作方式。 - MH.
为什么不使用服务? - Andrew Kirkegaard
我不想在睡眠模式下运行时错过任务。服务能否在空闲(睡眠)模式下保持活动状态?还是需要使用唤醒锁定?相对于AlarmManager,服务的资源使用情况如何(现在我正在尝试使用AlarmManager)? - kuma DK
3个回答

7
你可以扩展Application类并在其中完成你的工作。
public class App extends Application {

    private Handler handler;

    @Override
    protected void onCreate() {
        super.onCreate();
        handler = new Handler(); // new handler
        handler.postDelayed(runnable, 1000*60*10); // 10 mins int.
        setContentView(R.layout.activity_pro__sms);
    } 

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            /* my set of codes for repeated work */
            foobar();
            handler.postDelayed(this, 1000*60*10); // reschedule the handler
        }
    };
}

在清单文件中声明你的类:

<application android:name=".App">

编辑

但是,只有当您的应用正在运行时才会生效,否则您可以使用AlarmManager


谢谢。我会尝试并在几分钟内回复您。 - kuma DK
实际上我想要的是防止创建多个处理程序。 在Android开发者网站上,他们说Handler是最合适的方法。 - kuma DK
2
Vang 给你的代码只会创建一个 handler,并根据经过的时间重复执行该过程。请注意,他扩展了 Application 类,该类仅在应用程序创建时调用一次(即当您启动应用程序时)。如果您完全销毁应用程序,则 handler 将停止工作,否则每次只能运行一个 handler。如果您正在寻找一个持续运行的 handler,请使用如上所述的 AlarmManager。 - NightwareSystems
感谢Vang和NightwareSystems的评论。我已经明白我应该使用AlarmManager而不是Handler类。Vang所发布的内容对于Handlers来说是完美的,但我需要的是像你建议的AlarmManager。再次感谢你们的想法... - kuma DK

5
我决定回答自己的问题,因为我已经找到了正确的方法。Android的方法。首先,我在尝试并发布问题时所做的是对我的要求的错误方法。现在我正在发布这篇文章,以便其他人不会走错路,而是采用以下方式。
Android有几个计时选项。
1. Timer-task -> 在应用程序存活时运行。最适合短期计时。资源使用率更高。 2. Handler -> 在应用程序存活时运行。但不适合用作调度程序。(这就是我所问的,也不是正确的方法)。处理程序是重复执行某些操作直到应用程序被杀死的最佳方法。 3. Alarm-manager -> 即使应用程序被杀死,也是将某些事情安排在将来发生的最佳方式。(这就是我应该为我的应用程序应用的方法)。
这就是我找出来的。如果我错了,请纠正我。

4
这是不正确的。Handler 只是在应用程序线程上安排任务。当应用程序关闭时,Handler 任务也会结束。 - G. Blake Meike
当调用“postDelayed(Runnable,long)”方法时会发生什么?它会保持应用程序线程处于活动状态,以便触发可运行对象。 - kuma DK
2
不!延迟事件将永远不会发生。 - G. Blake Meike

1

首先定义一个实用类

public abstract class HandlerPeriodRunnable implements Runnable {

    private Handler periodHandler;
    private int msPeriod;

    public HandlerPeriodRunnable(Handler periodHandler, int msPeriod) {
        this.periodHandler = periodHandler;
        this.msPeriod = msPeriod;
    }

    @Override
    public void run() {
        periodRun();
        if (msPeriod > 0) {
            periodHandler.postDelayed(this, msPeriod);
        }
    }

    abstract public void periodRun();
}

然后使用它。
final Handler mUIHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mUIHandler.postDelayed(new HandlerPeriodRunnable(mUIHandler, 1000) {
        @Override
        public void periodRun() {

        }
    }, 2000);
}

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