我的理解是,现有的屏幕关闭和打开并不意味着设备分别处于睡眠和唤醒状态。设备上的任何应用程序都持有部分唤醒锁定,设备不会处于深度睡眠状态,但屏幕可能关闭/打开。
是否有任何意图监听CPU“唤醒”和“睡眠”?
有没有办法,我们知道CPU是从深度睡眠中唤醒的?
发布于 2019-05-05 05:19:08
我需要一个工具来在后台对我的应用程序的一些计时行为进行故障排除时做到这一点。所以我创建了自己的类来做这件事。请参阅下面的代码。下面是你如何使用它:
CpuSleepDetector.getInstance().setSleepEndNotifier(new CpuSleepDetector.SleepEndNotifier() {
@Override
public void cpuSleepEnded(long sleepDurationMillis) {
Log.d(TAG, "The CPU just exited sleep. It was sleeping for "+sleepDurationMillis+" ms.");
}
});
CpuSleepDetector.getInstance().logDump();logDump方法会将最后100个睡眠事件转储到LogCat。这在故障排除中很有用,因为要让中央处理器进入睡眠状态,我不仅要断开USB线与手机的连接,还必须关闭通过WiFi的adb连接。这样,您可以在以后重新连接adb,并使用logDump方法获取最近的检测结果。
我知道这是一个古老的问题,但希望这对其他人有用。
以下是检测器类的代码:
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
public class CpuSleepDetector {
private static final String TAG = CpuSleepDetector.class.getSimpleName();
private static CpuSleepDetector instance = null;
private HandlerThread thread;
private Handler handler;
private SleepEndNotifier notifier;
public static CpuSleepDetector getInstance() {
if (instance == null) {
instance = new CpuSleepDetector();
}
return instance;
}
private CpuSleepDetector() {
thread = new HandlerThread("cpuSleepDetectorThread");
thread.start();
handler = new Handler(thread.getLooper());
watchForSleep();
}
private void watchForSleep(){
// uptime stalls when cpu stalls
final long uptimeAtStart = SystemClock.uptimeMillis();
final long realtimeAtStart = SystemClock.elapsedRealtime();
handler.postDelayed(new Runnable() {
@Override
public void run() {
long uptimeAtEnd = SystemClock.uptimeMillis();
long realtimeAtEnd = SystemClock.elapsedRealtime();
long realtimeDelta = realtimeAtEnd - realtimeAtStart;
long uptimeDelta = uptimeAtEnd - uptimeAtStart;
final long sleepTime = realtimeDelta - uptimeDelta;
if (sleepTime > 1) {
detectedStalls.put(new Date(), sleepTime);
prune();
if (notifier != null) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
notifier.cpuSleepEnded(sleepTime);
}
});
}
}
watchForSleep();
}
}, 1000);
}
private HashMap<Date,Long> detectedStalls = new HashMap<Date,Long>();
private HashMap<Date,Long> getDetectedStalls() {
return detectedStalls;
}
private void prune() {
int numberToPrune = detectedStalls.size() - 100;
if (numberToPrune > 0) {
HashMap<Date,Long> newDetectedStalls = new HashMap<Date,Long>();
ArrayList<Date> dates = new ArrayList<>(getDetectedStalls().keySet());
Collections.sort(dates);
for (int i = numberToPrune; i < detectedStalls.size(); i++) {
newDetectedStalls.put(dates.get(i), detectedStalls.get(dates.get(i)));
}
detectedStalls = newDetectedStalls;
}
}
public void logDump() {
Log.d(TAG, "Last 100 known CPU sleep incidents:");
ArrayList<Date> dates = new ArrayList<>(getDetectedStalls().keySet());
Collections.sort(dates);
for (Date date: dates) {
Log.d(TAG, ""+date+": "+getDetectedStalls().get(date));
}
}
public void setSleepEndNotifier(SleepEndNotifier notifier) {
this.notifier = notifier;
}
public interface SleepEndNotifier {
public void cpuSleepEnded(long sleepDurationMillis);
}
}https://stackoverflow.com/questions/28536504
复制相似问题