【问题标题】:PowerManager.PARTIAL_WAKE_LOCK androidPowerManager.PARTIAL_WAKE_LOCK 安卓
【发布时间】:2013-12-02 05:27:09
【问题描述】:

我很困惑是否要获取这个唤醒锁。例如。我有这种类型的代码是从BroadcastReceiever(CONNECTIVITY_CHANGE、BOOT_COMPLETED 等)异步onReceive() 调用的,即我正在从onReceive() 启动一个IntentService,它执行繁重的工作。

private static void insertInDatabase(Context context /*, some data to be inserted in database*/) {
        Database helper = Database.getInstance(context);
        PowerManager pm = (PowerManager) context
            .getSystemService(Context.POWER_SERVICE);
        final WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakelockName); 
        wakeLock.acquire();
        try { 
            SQLiteDatabase db = helper.getWritableDatabase();
            ContentValues cv = new ContentValues();
            // insert data in database here  
        } finally {
            wakeLock.release();
        }
    }

这种情况是否适合收购PowerManager.PARTIAL_WAKE_LOCK

【问题讨论】:

  • 看我的回答 - 如果你只是获得服务中的锁定将无法工作

标签: android broadcastreceiver android-sqlite wakelock android-wake-lock


【解决方案1】:

@paha 的回答忽略了一个重点:IntentService 是不够的。在onReceive() 结束和 IntentService 启动之间,手机可能会再次入睡。你需要一个(静态)锁来弥补这个差距——这在 Mark Murpphy 的WakefulIntentService 中实现了@

所以保留 AlarmManager 和接收器,但从您的 onReceive() 启动 WakefulIntentService

见:

【讨论】:

  • 没错,这是我关心的问题,事实上我已经实现了静态唤醒锁,因为startService() 不是同步的。有问题的代码只是解释的示例代码。我只是好奇它是否是获取唤醒锁的正确方案。因为我找不到很多使用它的样本,而且很难手动产生问题。
  • @M-WaJeEh:所以您在接收时使用静态方法启动您的服务,该方法也获取锁
  • 是的,该静态方法负责启动IntentService,但它在调用startService() 之前获得了唤醒锁。所以锁也是静态的。
  • 这是正确的方法,对吧?只是我们的应用程序显示的唤醒锁定时间比我们预期的要长。我们正在使用唤醒锁定检测器应用程序,并从 Android 设置中的电池选项进行分析。所以我想为什么不也获得社会认可。
  • 是的WakefulIntentService 也在做同样的事情,它只是有一些我们不需要的AlarmManager 的实用方法。谢谢你的时间兄弟。
【解决方案2】:

方法onReceive() 正在主应用程序线程上运行,您不知道insertInDatabase() 需要多长时间。 使用IntentService 进行数据库插入和安排警报。 IntentService 将在后台线程上调用您的onHandleIntent(),这样您就可以花时间,当onHandleIntent() 完成时,该服务会自动消失。

public class MyIntentService extends IntentService {

    @Override
    protected void onHandleIntent(Intent intent) {
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        final WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakelockName); 
        wakeLock.acquire();
        wl.acquire();
        try { 
            SQLiteDatabase db = helper.getWritableDatabase();
            ContentValues cv = new ContentValues();
            // insert data in database here  
        } finally {
            wakeLock.release();
        }
    }
}

要从BroadcastReceiver 开始IntentService,请使用AlarmManagerIntentService 作为队列模式工作,您无需担心操作的同步性。

在 cmets 讨论后添加:

您的代码示例没有说明您从哪里调用PARTIAL_WAKE_LOCK。简短的回答是BroadcastReciever 不需要PARTIAL_WAKE_LOCKIntentService 需要PARTIAL_WAKE_LOCK。也许这会有所帮助BroadcastReceiver, Service and Wakelock

【讨论】:

  • 感谢您的回答,但我想您在这里错过了我的意思,我已经在onReceive() 中启动了IntentService。我的问题是我需要PARTIAL_WAKE_LOCK吗?
  • 让我也澄清一下这个问题,尽管我使用了异步这个词。
  • @M-WaJeEh 我通过添加一些信息更新了答案。可能我没有完全理解您的问题,如果您没有找到答案,请详细说明。
  • 我的问题是我需要PARTIAL_WAKE_LOCK吗?我的问题与IntentService 的内部工作无关,或者onRecive() 默认情况下是否在UI 线程上调用等等。换句话说,我的问题是“如果处于深度睡眠状态,Android 唤醒发送广播。它可以去吗?立即再次入睡?即使我从onReceive() 启动了一项服务,Android 会等待我的服务完成还是我需要明确要求PARTIAL_WAKE_LOCK。我想我再清楚不过了。
  • @M-WaJeEh 您的代码示例没有说明您从哪个地方调用 PARTIAL_WAKE_LOCK。简短的回答是,BroadcastReciever 中不需要 LOCK,而 IntentService 中需要 LOCK。也许这会有所帮助stackoverflow.com/questions/5681071/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2017-12-05
  • 2012-04-08
  • 2012-10-09
  • 2014-06-09
相关资源
最近更新 更多