PowerManager.PARTIAL_WAKE_LOCK android

风流意气都作罢 提交于 2019-11-26 14:55:29

问题


I am very confused whether to acquire this wakelock. E.g. I have this type of code that is called from onReceive() of a BroadcastReceiever (CONNECTIVITY_CHANGE, BOOT_COMPLETED etc) asynchronously i.e. I am launching an IntentService from onReceive() which performs heavy lifting.

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();
        }
    }

Is this scenario the right candidate to acquire PowerManager.PARTIAL_WAKE_LOCK?


回答1:


The answer by @paha misses an important point : IntentService is not enough. Between onReceive() ends and the IntentService is started the phone might fall asleep again. You need a (static) lock to bridge this gap - this is implemented in Mark Murpphy's WakefulIntentService

So keep the AlarmManager and receiver but launch a WakefulIntentService from your onReceive().

See:

  • Android deep sleep and wake locks
  • PowerManager wakelock not waking device up from service



回答2:


Method onReceive() is running on the main application thread and you do not know how long insertInDatabase() will take. Use an IntentService for doing the database insert and scheduling your alarms. The IntentService will call your onHandleIntent() on a background thread, so you can take the time you need, and the service automatically goes away when onHandleIntent() completes.

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();
        }
    }
}

To start IntentService from BroadcastReceiver use AlarmManager. IntentService work as queue pattern and you don't need to worry about synchronicity of operations.

Added after discussion in comments:

Your code example does not say from what place you call PARTIAL_WAKE_LOCK. The short answer is PARTIAL_WAKE_LOCK is not needed in the BroadcastReciever and PARTIAL_WAKE_LOCK is needed in the IntentService. Maybe this will help BroadcastReceiver, Service and Wakelock



来源:https://stackoverflow.com/questions/20321444/powermanager-partial-wake-lock-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!