Android 每分钟运行一次的服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21974587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:23:19  来源:igfitidea点击:

Service that runs every minute

androidservicealarmmanager

提问by AggieDev

I have a service that I am wanting to execute a task every minute in the background. It does not need to execute the task whenever the phone is asleep, only when the user is actively using it. I am trying to do this with an IntentService which is set up as follows:

我有一项服务,我想在后台每分钟执行一次任务。它不需要在手机休眠时执行任务,只有在用户积极使用它时才需要执行任务。我正在尝试使用设置如下的 IntentService 来做到这一点:

public class CounterService extends IntentService{

    public CounterService() {
        super("CounterService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       return super.onStartCommand(intent,flags,startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Toast.makeText(this, "onhandleintent", Toast.LENGTH_SHORT).show();
        while(true)
        {
            //one minute is 60*1000
            try {
                Thread.sleep(5 * 1000);
                Toast.makeText(getApplicationContext(), "getting app count", Toast.LENGTH_LONG).show();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Right now to get the functionality working I simply want it to display a toast every 5 seconds, I will change it to one minute later. If I have the while(true)commented out, then the "onhandleintent" message is displayed. However if I have the following code run, neither of the Toasts display. How can I fix this?

现在为了使功能正常工作,我只是希望它每 5 秒显示一次祝酒词,我会将其更改为一分钟后。如果我已while(true)注释掉,则会显示“onhandleintent”消息。但是,如果我运行以下代码,则 Toasts 都不会显示。我怎样才能解决这个问题?

回答by Android Newbie

This will send an intent to your service every minute without using any processor time in your activity in between

这将每分钟向您的服务发送一个意图,而不会在您的活动中使用任何处理器时间

  Intent myIntent = new Intent(context, MyServiceReceiver.class);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context,  0, myIntent, 0);

  AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
  Calendar calendar = Calendar.getInstance();
  calendar.setTimeInMillis(System.currentTimeMillis());
  calendar.add(Calendar.SECOND, 60); // first time
  long frequency= 60 * 1000; // in ms 
  alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), frequency, pendingIntent);           

Adjust MyServiceReceiver.class to match your target service or activity. The documentationprovides more details to fine-tune your calls like whether you want exact timing, execution at a specific time of the day ...

调整 MyServiceReceiver.class 以匹配您的目标服务或活动。该文档提供了更多详细信息来微调您的调用,例如您是否需要准确的时间、在一天中的特定时间执行...

回答by jeremyvillalobos

You need to exit the main thread to avoid risking a ANR.

您需要退出主线程以避免 ANR 的风险。

Instead add a Handler

而是添加一个处理程序

Handler mHandler = new Handler();

...

@Override
protected void onHandleIntent(Intent intent) {
    Toast.makeText(this, "onhandleintent", Toast.LENGTH_SHORT).show();
    mHandler.postDelayed( ToastRunnable, 5000);
    //while(true)
    //{

        //one minute is 60*1000
        //try {
        //    Thread.sleep(5 * 1000);
        //    Toast.makeText(getApplicationContext(), "getting app count",          
        //Toast.LENGTH_LONG).show();
        //} catch (InterruptedException e) {
            // TODO Auto-generated catch block
        //    e.printStackTrace();
        //}
    //}
}
final Runnable ToastRunnable = new Runnable(){
    public void run(){
         Toast.makeText(getApplicationContext(), "getting app count",          
               Toast.LENGTH_LONG).show();
         mHandler.postDelayed( ToastRunnable, 5000);
    }
}

回答by Prashant Yadav

Do it like this

像这样做

    private void ping() {
    try {
        //Your code here or call a method
    } catch (Exception e) {
        Log.e("Error", "In onStartCommand");
        e.printStackTrace();
    }
      scheduleNext();
    }

    private void scheduleNext() {
      mHandler.postDelayed(new Runnable() {
        public void run() { ping(); }
      }, 60000);
    }

    public int onStartCommand(Intent intent, int x, int y) {
      mHandler = new android.os.Handler();
      ping();
      return START_STICKY;
    }