有关AlarmManager和WakeLocks的查询

时间:2015-02-07 22:18:53

标签: android alarmmanager wakelock android-wake-lock repeatingalarm

我正在开发一个原生Android应用程序,每30分钟运行一次备份操作。

我正在使用AlarmManager来实现此目的,它运行正常。这是我用来启动警报的代码:

public static void startSync(Context context) {
        alarmIntent = new Intent(context, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
        manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
       // int interval = 3600000;
        int interval =30000 ;
        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

        ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
        Toast.makeText(context, "Sync Started", Toast.LENGTH_SHORT).show();
    }

这是接收方法:

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent arg1) {
        PowerManager pm = (PowerManager) context.getSystemService(context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
        wl.acquire();
        Intent eventService = new Intent(context, SyncInBackground.class);
        context.startService(eventService);
        wl.release();
    }
}

我注意到当我的设备没有处于待机状态时,操作需要5秒钟(我以编程方式计算)但是当移动设备处于待机模式时需要11秒。这就是我在后台服务中运行备份操作之前使用wake_lock的原因,以便让应用只需5秒钟。

但是如果手机处于待机模式,我仍会得到相同的结果......如果不是待机模式,它仍需要11秒和5秒。

如何让我的后台服务在5秒而不是11秒内运行重复闹钟?

2 个答案:

答案 0 :(得分:1)

通常的错误:在OnReceive 中获取唤醒锁定什么都不做。 AlarmManager已经在OnReceive中保存了一个唤醒锁。当你/它运行时,你的方式是纯粹的运气。您必须使用WakefulBroadcastReceiver或使用WakefulIntentService。 WIS将获得一个静态唤醒锁定,它将在OnReceive返回和服务启动之间激活。

请在此处查看我的回答:Wake Lock not working properly了解链接。

答案 1 :(得分:0)

问题是context.startService(eventService)是一个异步操作,很可能在几毫秒内返回。这意味着当您在WakeLock方法中获得onReceive时,只需将其保留几毫秒,然后在服务启动之前释放。

解决此问题的方法是在您的BroadcastReceiver和您尝试启动的服务之间共享一个唤醒锁。这就是WakefulIntentService的工作原理,但你也可以自己做,例如,通过两个方法创建单例WakelockManager,一个用于获取,一个用于释放唤醒锁,然后让BroadcastReceiver调用前者和你的服务叫后者。

另外,请记住泄漏的唤醒锁(通过购买一个而忘记释放它)会对电池使用造成严重后果。