网站与云平台区别,企业网站建设有什么要求,网站建设预算明细,网站建设收费标准讯息WakefulBroadcastReceiver 是一种特殊类型的广播接收器#xff0c;为应用创建和管理 PARTIAL_WAKE_LOCK 。
简单来说#xff0c; WakefulBroadcastReceiver 是持有系统唤醒锁的 BroadcastReceiver #xff0c;用于执行需要保持CPU运转的场景。
注册
注册 Receiver #…WakefulBroadcastReceiver 是一种特殊类型的广播接收器为应用创建和管理 PARTIAL_WAKE_LOCK 。
简单来说 WakefulBroadcastReceiver 是持有系统唤醒锁的 BroadcastReceiver 用于执行需要保持CPU运转的场景。
注册
注册 Receiver
receiver android:name.MyWakefulReceiver/receiver实现MyWakefulReceiver
重写 onReceive() 方法使用 startWakefulService(Context context, Intent intent) 启动 Service public class MyWakefulReceiver extends WakefulBroadcastReceiver {Overridepublic void onReceive(Context context, Intent intent) {// Start the service, keeping the device awake while the service is// launching. This is the Intent to deliver to the service.Intent service new Intent(context, MyIntentService.class);startWakefulService(context, service);}}
Service
Service 里执行正常的逻辑实行结束后调用 MyWakefulReceiver.completeWakefulIntent(Intent intent) 方法。
public class MyIntentService extends IntentService {public MyIntentService() {super(MyIntentService);}Overrideprotected void onHandleIntent(Intent intent) {Bundle extras intent.getExtras();// Do the work that requires your app to keep the CPU running.// ...// Release the wake lock provided by the WakefulBroadcastReceiver.MyWakefulReceiver.completeWakefulIntent(intent);}
}源码分析
在 startWakefulService(Context context, Intent intent) 方法中通过 PowerManager.WakeLock 持有了系统锁并为每个 intent 设置了一个 id 用于标识存储在 sActiveWakeLocks 数组中
/*** Do a {link android.content.Context#startService(android.content.Intent)* Context.startService}, but holding a wake lock while the service starts.* This will modify the Intent to hold an extra identifying the wake lock;* when the service receives it in {link android.app.Service#onStartCommand* Service.onStartCommand}, it should pass back the Intent it receives there to* {link #completeWakefulIntent(android.content.Intent)} in order to release* the wake lock.** param context The Context in which it operate.* param intent The Intent with which to start the service, as per* {link android.content.Context#startService(android.content.Intent)* Context.startService}.*/public static ComponentName startWakefulService(Context context, Intent intent) {synchronized (sActiveWakeLocks) {int id mNextId;mNextId;if (mNextId 0) {mNextId 1;}intent.putExtra(EXTRA_WAKE_LOCK_ID, id);ComponentName comp context.startService(intent);if (comp null) {return null;}PowerManager pm (PowerManager)context.getSystemService(Context.POWER_SERVICE);PowerManager.WakeLock wl pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,androidx.core:wake: comp.flattenToShortString());wl.setReferenceCounted(false);wl.acquire(60 * 1000);sActiveWakeLocks.put(id, wl);return comp;}}当 Service 调用 MyWakefulReceiver.completeWakefulIntent(Intent intent) 方法时释放系统锁并根据 id 将此锁从数组中移除
/*** Finish the execution from a previous {link #startWakefulService}. Any wake lock* that was being held will now be released.** param intent The Intent as originally generated by {link #startWakefulService}.* return Returns true if the intent is associated with a wake lock that is* now released; returns false if there was no wake lock specified for it.*/public static boolean completeWakefulIntent(Intent intent) {final int id intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);if (id 0) {return false;}synchronized (sActiveWakeLocks) {PowerManager.WakeLock wl sActiveWakeLocks.get(id);if (wl ! null) {wl.release();sActiveWakeLocks.remove(id);return true;}// We return true whether or not we actually found the wake lock// the return code is defined to indicate whether the Intent contained// an identifier for a wake lock that it was supposed to match.// We just log a warning here if there is no wake lock found, which could// happen for example if this function is called twice on the same// intent or the process is killed and restarted before processing the intent.Log.w(WakefulBroadcastReceiv., No active wake lock id # id);return true;}}