AlarmManager 和 WakeLocks 相关查询
Inquiry related to AlarmManager and WakeLocks
我正在开发一个本机 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 秒内发出重复警报?
问题是 context.startService(eventService)
是一个异步操作,很可能 return 只需几毫秒。这意味着当您在 onReceive
方法中获取 WakeLock
时,您只需将其保留几毫秒,然后在服务启动前释放。
解决此问题的一种方法是在您的 BroadcastReceiver 和您尝试启动的服务之间共享唤醒锁。这就是 WakefulIntentService 的工作方式,但您也可以自己执行此操作,例如,通过创建一个具有两种方法的单例 WakelockManager,一种用于获取唤醒锁,一种用于释放唤醒锁,然后让 BroadcastReceiver 调用前者和您的服务叫后者。
此外,请记住泄漏的唤醒锁(通过获取一个但忘记释放它)可能会在电池使用方面造成严重后果。
常见错误:在 OnReceive 中获取唤醒锁没有任何作用。 AlarmManager 已经在 OnReceive 中持有一个唤醒锁。 你的方法成功完全是运气,when/if 它成功了。您必须使用 WakefulBroadcastReceiver 或使用 WakefulIntentService。 WIS 将获取一个静态唤醒锁,该锁将在 OnReceive 返回和服务启动之间激活。
在这里查看我的回答:Wake Lock not working properly 链接。
我正在开发一个本机 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 秒内发出重复警报?
问题是 context.startService(eventService)
是一个异步操作,很可能 return 只需几毫秒。这意味着当您在 onReceive
方法中获取 WakeLock
时,您只需将其保留几毫秒,然后在服务启动前释放。
解决此问题的一种方法是在您的 BroadcastReceiver 和您尝试启动的服务之间共享唤醒锁。这就是 WakefulIntentService 的工作方式,但您也可以自己执行此操作,例如,通过创建一个具有两种方法的单例 WakelockManager,一种用于获取唤醒锁,一种用于释放唤醒锁,然后让 BroadcastReceiver 调用前者和您的服务叫后者。
此外,请记住泄漏的唤醒锁(通过获取一个但忘记释放它)可能会在电池使用方面造成严重后果。
常见错误:在 OnReceive 中获取唤醒锁没有任何作用。 AlarmManager 已经在 OnReceive 中持有一个唤醒锁。 你的方法成功完全是运气,when/if 它成功了。您必须使用 WakefulBroadcastReceiver 或使用 WakefulIntentService。 WIS 将获取一个静态唤醒锁,该锁将在 OnReceive 返回和服务启动之间激活。
在这里查看我的回答:Wake Lock not working properly 链接。