1

我正在开发一个原生的android应用程序,每30分钟运行一次备份操作。与AlarmManager和WakeLocks相关的问题

我使用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秒?

回答

1

通常的错误:在OnReceive 中获取唤醒锁不会做任何事情。 AlarmManager已经在OnReceive中保存了一个唤醒锁。你的方式运行纯运气,当/如果它的工作。您必须使用WakefulBroadcastReceiver或使用WakefulIntentService。 WIS将获得一个静态唤醒锁,它将在OnReceive返回和服务启动之间激活。

看到我的答案在这里:Wake Lock not working properly的链接。

0

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

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

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