這一片文章是朋友發(fā)給我的,如有原文出處,請(qǐng)聯(lián)系我注明出處。
當(dāng)Android設(shè)備空閑時(shí),屏幕會(huì)變暗,然后關(guān)閉屏幕,最后會(huì)停止CPU的運(yùn)行,這樣可以防止電池電量掉的快。在休眠過程中自定義的Timer、Handler、Thread、Service等都會(huì)暫停。但有些時(shí)候我們需要改變Android系統(tǒng)默認(rèn)的這種狀態(tài):比如玩游戲時(shí)我們需要保持屏幕常亮,比如一些下載操作不需要屏幕常亮但需要CPU一直運(yùn)行直到任務(wù)完成。
保持屏幕常亮
最好的方式是在Activity中使用FLAG_KEEP_SCREEN_ON 的Flag。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
這個(gè)方法的好處是不像喚醒鎖(wake locks),需要一些特定的權(quán)限(permission)。并且能正確管理不同app之間的切換,不用擔(dān)心無用資源的釋放問題。
另一個(gè)方式是在布局文件中使用android:keepScreenOn屬性:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
...
</RelativeLayout>
android:keepScreenOn = ” true “的作用和FLAG_KEEP_SCREEN_ON一樣。使用代碼的好處是你允許你在需要的地方關(guān)閉屏幕。
注意:一般不需要人為的去掉FLAG_KEEP_SCREEN_ON的flag,windowManager會(huì)管理好程序進(jìn)入后臺(tái)回到前臺(tái)的的操作。如果確實(shí)需要手動(dòng)清掉常亮的flag,使用getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
保持CPU運(yùn)行
需要使用PowerManager這個(gè)系統(tǒng)服務(wù)的喚醒鎖(wake locks)特征來保持CPU處于喚醒狀態(tài)。喚醒鎖允許程序控制宿主設(shè)備的電量狀態(tài)。創(chuàng)建和持有喚醒鎖對(duì)電池的續(xù)航有較大的影響,所以,除非是真的需要喚醒鎖完成盡可能短的時(shí)間在后臺(tái)完成的任務(wù)時(shí)才使用它。比如在Acitivity中就沒必要用了。如果需要關(guān)閉屏幕,使用上述的FLAG_KEEP_SCREEN_ON。 只有一種合理的使用場(chǎng)景,是在使用后臺(tái)服務(wù)在屏幕關(guān)閉情況下hold住CPU完成一些工作。 要使用喚醒鎖,如果不使用喚醒鎖來執(zhí)行后臺(tái)服務(wù),不能保證因CPU休眠未來的某個(gè)時(shí)刻任務(wù)會(huì)停止,這不是我們想要的。 (有的人可能認(rèn)為我以前寫的后臺(tái)服務(wù)就沒掉過鏈子呀運(yùn)行得挺好的,1.可能是你的任務(wù)時(shí)間比較短;2.可能CPU被手機(jī)里面很多其他的軟件一直在喚醒狀態(tài)。)。下面是很多網(wǎng)友有同樣的問題:
image.png
喚醒鎖可劃分為并識(shí)別四種用戶喚醒鎖:
image.png
請(qǐng)注意,自 API 等級(jí) 17 開始,FULL_WAKE_LOCK將被棄用。 應(yīng)用應(yīng)使用 FLAG_KEEP_SCREEN_ON。
第一步就是添加喚醒鎖權(quán)限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
直接使用喚醒鎖:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakelockTag");
wakeLock.acquire();
注意:在使用該類的時(shí)候,必須保證acquire和release是成對(duì)出現(xiàn)的。

