Android 开机跳过ANR

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

猜你喜欢

转载自blog.csdn.net/wd229047557/article/details/82260414