1.原因
在有些低端手机芯片会发现,开机向导时候很容易出现各种gms应用anr的情况,都是因为cpu高导致。但是对性能不好的芯片来说,很容易导致anr,因此解决方法1就是跳过skip anr。
2.实现判断时间
搜索add start ,add end
xref: /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void finishBooting() {
...
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
/// M: AMEventHook event @{
AMEventHookData.BeforeSendBootCompleted eventData =
AMEventHookData.BeforeSendBootCompleted.createInstance();
AMEventHookResult eventResult =
mAMEventHook.hook(AMEventHook.Event.AM_BeforeSendBootCompleted,
eventData);
if (AMEventHookResult.hasAction(eventResult,
AMEventHookAction.AM_Interrupt)) {
return;
}
/// M: AMEventHook event @}
/// M: AMS log enhancement @{
Slog.v(TAG, "broadcast BOOT_COMPLETED intent");
/// @}
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
//add start, set boot_completed_time (in ms) to property
SystemProperties.set("sys.boot_completed_time", String.valueOf(SystemClock.uptimeMillis()));
Slog.d(TAG, "set sys.boot_completed_time = " + String.valueOf(SystemClock.uptimeMillis()));
// add end
// And trigger dev.bootcomplete if we are not showing encryption progress
if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
|| "".equals(SystemProperties.get("vold.encrypt_progress"))) {
SystemProperties.set("dev.bootcomplete", "1");
}
...
}
}
/// M: ANR debug mechanism for defer ANR @{
/// M: Inform ANR manager boot completed
mANRManager.writeEvent(ANRManager.EVENT_BOOT_COMPLETED);
/// M: ANR debug mechanism for defer ANR @}
}
/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
void stopReportingCrashesLocked(ProcessRecord proc) {
if (mAppsNotReportingCrashes == null) {
mAppsNotReportingCrashes = new ArraySet<>();
}
mAppsNotReportingCrashes.add(proc.info.packageName);
}
//add start, boot completed time < 5min, skip anr
boolean isBootCompletedLongEnough(long duration) {
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {// boot completed
String completedTimeString = SystemProperties.get("sys.boot_completed_time");
long expectedTime = Long.parseLong(completedTimeString) + duration;
long currTime = SystemClock.uptimeMillis();
Slog.d(TAG, "expectedTime = " + expectedTime + ", currTime = " + currTime);
return currTime > expectedTime;
}
return false;
}
//add end
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
ActivityRecord parent, boolean aboveSystem, final String annotation) {
/// M: ANR debug mechanism for skip ANR @{
if (mService.mANRManager.isANRFlowSkipped(app.pid, app.processName, annotation,
mService.mShuttingDown, app.notResponding, app.crashing) == true) {
return;
}
/// M: ANR debug mechanism for skip ANR @}
//开机5分钟内,跳过因LOCALE_CHANGED导致的anr,这里可以更改条件
//add start, boot completed time < 5min, skip anr
if (!isBootCompletedLongEnough(5 * 1000 * 60) && annotation != null
&& annotation.contains("android.intent.action.LOCALE_CHANGED")) {
Slog.d(TAG, "skip anr when booting");
return;
}
//add end
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
...
}
3.cpu另一种解法
由于开机cpu占用高导致问题,可以在开机时所有cpu core都来跑,开机完成时候把cpu 频率还原
比如:在init.rc中写cpu节点来升频,然后完成之后可以通过rc中的 on命令来
//也可以自定义个属性来操作
on boot
write /sys/devices/system/cpu/cpufreq/interactive/target_loads 0 //升频
on property:sys.boot_completed=1
write /sys/devices/system/cpu/cpufreq/interactive/target_loads 1 //还原cpu