How can repeating AlarmManager start AsyncTask?

2019-02-20 09:16发布

I usually write this code to start a service with AlarmManager.

    intent = new Intent(getActivity(), someservice.class);
    pendingNotificationIntent = PendingIntent.getService(getActivity(), 0, intent, 0);
    alarm = (AlarmManager) getActivity().getSystemService(getActivity().ALARM_SERVICE);
    int interval = 30 * 1000;
    long now = Calendar.getInstance().getTimeInMillis();
    alarm.setRepeating(AlarmManager.RTC_WAKEUP, now, interval, pendingNotificationIntent);

My AsyncTask is a private class where I register AlarmManager object.

How can I call the AsyncTask instead of a service using AlarmManager object?

PS. If there is a better way to run AsyncTask every X seconds/minutes, please propose it!

2条回答
干净又极端
2楼-- · 2019-02-20 09:52

Based upon munish-katoch's response, I have the following concrete solution.

Set an alarm:

Intent intent = new Intent(context, AlarmReceiver.class);

PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
  SystemClock.elapsedRealtime() + 5 * 1000, 60 * 1000, alarmIntent);

The above code configures AlarmManager to fire at AlarmReceiver, which is defined as follows:

public class AlarmReceiver extends WakefulBroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {  
    new MyAsyncTask.execute();
  }
}

In the event of an alarm AlarmReceiver starts MyAsyncTask.

Here be dragons

There are life cycle issues associated with instantiating an AsyncTask from a WakefulBroadcastReceiver, i.e., the above solution can lead to MyAsyncTask being killed prematurely. Moreover, threading rules are violated.

查看更多
劫难
3楼-- · 2019-02-20 09:53

This is how you can do it:

1.) Define a static intent (intent1) and use it to pass to AlarmManager when setting time. So now when ever time, will lapse; AlarmManager will notify by sending intent1.

2.) On onReceive of BroadcastReceiver of intent1, start a AsyncTask. At end end of AsyncTask, set the next time for AlarmManager.

查看更多
登录 后发表回答