🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
1. newWakeLock分析 通过PowerManager(以后简称PM)的newWakeLock将创建一个WakeLock,代码如下: ~~~ public WakeLock newWakeLock(int flags, String tag) { //tag不能为null,否则抛异常 return new WakeLock(flags, tag);//WakeLock为PM的内部类,第一个参数flags很关键 } ~~~ WakeLock的第一个参数flags很关键,它用于控制CPU/Screen/Keyboard的休眠状态。flags的可选值如表5-3所示。 :-: ![](https://box.kancloud.cn/e8422228b250e85dcf3079aa024e2cb4_755x281.png =755x281) 表5-3 WakeLock 的flags参数说明 由表5-3可知: - WakeLock只控制CPU、屏幕和键盘三大部分。 - 表中最后两项是附加标志,和前面的其他WAKE_LOCK标志组合使用。注意, PARTIAL_WAKE_LOCK比较特殊,附加标志不能影响它。 - PARTIAL_WAKE_LOCK不受电源键控制,即按电源键不能使PARTIAL_WAKE_LOCK系统进入休眠状态(屏幕可以关闭,但CPU不会休眠)。 了解了上述知识后,再来看如下代码: **PowerManager.java::WakeLock** ~~~ WakeLock(int flags, String tag) { //检查flags参数是否非法 mFlags =flags; mTag =tag; //创建一个Binder对象,除了做Token外,PMS需要监视客户端的生死状况,否则有可能导致 //WakeLock不能被释放 mToken= new Binder(); } ~~~ 客户端创建WakeLock后,需要调用acquire以确保电力资源供应正常。下面对acquire代码进行分析。 2. acquire分析 **PowerManager.java::WakeLock.acquire函数** ~~~ public void acquire() { synchronized (mToken) { acquireLocked();//调用acquireLocked函数 } } //acquireLoced函数 private void acquireLocked() { if(!mRefCounted || mCount++ == 0) { mHandler.removeCallbacks(mReleaser);//引用计数控制 try { //调用PMS的acquirewakeLock,注意这里传递的参数,其中mWorkSource为空 mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource); }...... mHeld =true; } } ~~~ 上边代码中调用PMS的acquireWakeLock函数与PMS交互,该函数最后一个参数为WorkSource类。这个类从Android 2.2开始就存在,但一直没有明确的作用,下面是关于它的一段说明。 ~~~ /** 见WorkSoure.java * Describesthe source of some work that may be done by someone else. * Currentlythe public representation of what a work source is is not * defined;this is an opaque container. */ ~~~ 由以上注释可知,WorkSource本意用来描述某些任务的Source。传递此Source给其他人,这些人就可以执行该Source对应的工作。目前使用WorkSource的地方仅是ContentService中的SynManager。读者暂时可不理会WorkSource。 客户端的功能比较简单,和PMS仅通过acquireWakeLock函数交互。下面来分析服务端的工作。