简体   繁体   English

用于重复任务的 Android 处理程序 - 它会重叠吗? 定时器任务 VS 处理程序 VS 警报管理器

[英]Android Handler for repeated task - will it overlap ? Timer-task VS handler VS alarm-manager

I'm trying to build an Android app which will repeatedly run some process every 10 mins.我正在尝试构建一个 Android 应用程序,它将每 10 分钟重复运行一些进程。 As I found out Handlers are more reliable than timers or scheduling.我发现Handlers比计时器或调度更可靠。 So I'm going to develop my app using the Handlers using the given below codes.所以我将使用下面给出的代码使用Handlers开发我的应用Handlers

I'm little bit concerned that the below codes will create separate Handlers at each time I start the app and keep them running parallel, may be since I'm creating the Handler on onCreate .我有点担心下面的代码会在我每次启动应用Handlers时创建单独的Handlers程序并保持它们并行运行,可能是因为我在onCreate上创建了Handler

So what is the best way to keep only a single Handler runs in background at a time?那么,一次只让一个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
    }
};

You can extend Application class and do your work in it.您可以扩展 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
        }
    };
}

And declare your class in manifest:并在清单中声明您的类:

<application android:name=".App">

Edited已编辑

But it will work only if your app is running, otherwise you can use AlarmManager .但它只有在您的应用程序正在运行时才有效,否则您可以使用AlarmManager

I decided to answer my own question since I've found out how to do it right way.我决定回答我自己的问题,因为我已经找到了正确的方法。 The Android way.安卓方式。 First of all what I was trying to do and posted in the question is a wrong approach to my requirement.首先,我试图做并在问题中发布的是对我的要求的错误方法。 Now I'm posting this so someone else will not do it wrong way but the following way.现在我发布这个,所以其他人不会以错误的方式做,而是以下面的方式做。

Android has few options for timing. Android 几乎没有计时选项。

  1. Timer-task -> runs while application is alive.计时器任务 -> 在应用程序处于活动状态时运行。 best for short term timing.最适合短期计时。 Resource usage is higher.资源使用率更高。

  2. Handler -> runs while application is alive.处理程序 -> 在应用程序处于活动状态时运行。 But not suitable to used as a scheduler.但不适合用作调度程序。 (this is what I've asked and it's not the correct way to do that). (这是我问的,这不是正确的方法)。 Handlers are the best way to do something repeatedly till the app is killed. Handlers是重复做某事直到应用程序被Handlers的最佳方式。

  3. Alarm-manager -> The best way to schedule something to happen in future even if the app is killed.警报管理器 -> 即使应用程序被终止,也可以安排将来发生的事情的最佳方式。 (this is what I should apply for my app). (这是我应该为我的应用程序申请的内容)。

This is what I figured out.这是我想出来的。 Correct me if I'm wrong.如果我错了纠正我。

first define an utility class首先定义一个实用程序类

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

then use it然后使用它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM