Android系统层屏蔽弹出停止运行对话框

项目场景:

车载项目,ATC8257-Android9.0系统平台,福田汽车P3系列项目

项目使用高德公版地图前提是无法获得任何高德定制服务,每次刷完机去切换语言系统会弹出"高德地图已停止运行"弹窗,严重影响用户使用体验


问题描述

项目使用高德公版地图前提是无法获得任何高德定制服务,每次刷完机去切换语言系统会弹出"高德地图已停止运行",但是刷完机先把高德打开一次再去切换语言就不会有这个问题,报错内容如下:
弹窗报错

07-02 16:17:41.637  4482  4482 D AndroidRuntime: Shutting down VM
07-02 16:17:41.638  4482  4482 E AndroidRuntime: FATAL EXCEPTION: main
07-02 16:17:41.638  4482  4482 E AndroidRuntime: Process: com.autonavi.amapauto, PID: 4482
07-02 16:17:41.638  4482  4482 E AndroidRuntime: java.lang.UnsatisfiedLinkError: No implementation found for void com.autonavi.amapauto.utils.LanguageUtils.nativeNotifyLangChange(java.lang.String) (tried Java_com_autonavi_amapauto_utils_LanguageUtils_nativeNotifyLangChange and Java_com_autonavi_amapauto_utils_LanguageUtils_nativeNotifyLangChange__Ljava_lang_String_2)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at com.autonavi.amapauto.utils.LanguageUtils.nativeNotifyLangChange(Native Method)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at com.autonavi.amapauto.utils.LanguageUtils.notifyLanageChange(LanguageUtils.java:4)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at com.autonavi.amapauto.common.LanguageChangeReceiver.onReceive(LanguageChangeReceiver.java:4)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.app.ActivityThread.handleReceiver(ActivityThread.java:3410)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.app.ActivityThread.access$1300(ActivityThread.java:206)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1689)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:193)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6702)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
07-02 16:17:41.638  4482  4482 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:994)

原因分析:

验证过刷完机先把高德打开一次再去切换语言就不会有这个问题,结合上面报错内容,分析是刷完机后高德接收语言切换的广播代码没有主动完成初始化,当系统切换语言的广播发送后高德无法处理导致弹出“高德地图已停止运行”弹窗。


解决方案:

授人以鱼不如授人以渔

1.既然出现这种系统弹窗,我思索的是能不能在系统里面把高德包名过滤掉,弹窗的地方先获取包名是高德包名就return,有了这种思路后第一步还是借助万能网络,很自然就搜到这篇CSDN博客
屏蔽弹出停止运行对话框
修改位置:frameworks\base\services\core\java\com\android\server\am\AppErrors.java
这篇博客给出了修改方法,但是并没有说在具体哪个代码块里面改,我们通过里面的mService.killAppAtUsersRequest(proc, null)这行代码去AppErrors.java里面搜索,发现handleShowAnrUi方法里面有一处,按照博客的方法这样加

    void handleShowAnrUi(Message msg) {
		Slog.w(TAG, "------------------handleShowAnrUi");
        Dialog dialogToShow = null;
        synchronized (mService) {
        
            //此处省略部分系统代码
			
			if(dialogToShow != null){// For don't show gaode-map <Stop running> dialog 
			    Slog.w(TAG, "------------------handleShowAnrUi ");
			    if(proc != null && proc.info.packageName.equals("com.autonavi.amapauto")){
				    Slog.w(TAG, "------------------Current app is gaode map, don't show <Stop running> dialog");
				    dialogToShow = null;
				    // Just kill the app if there is no dialog to be shown.
                    mService.killAppAtUsersRequest(proc, null);
			    }
		    }
        }

        // If we've created a crash dialog, show it without the lock held
        if (dialogToShow != null) {
            dialogToShow.show();
        }
    }

从上面博客里知道修改的位置是frameworks\base\services\core\java\com\android\server\am\AppErrors.java,修改后我们可以在Android目录下单编这个模块

android$ mmm frameworks/base/services

编译好后去out/target/product/ac8257_demo/system/framework/目录里面找services.jar,然后推到机器system/framework/下面替换原来的,reboot后执行切换语言高德仍然弹窗报错,查看我们加在handleShowAnrUi方法里面的打印没走,但是看另一条打印

01-01 08:01:01.931   589   748 I AppErrors: Showing crash dialog for package com.autonavi.amapauto u0

2.照例去AppErrors.java里面搜关键字,发现这条打印在handleShowAppErrorUi方法里面,遂在该方法里面添加代码如下

    void handleShowAppErrorUi(Message msg) {
        AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;

        AppErrorDialog dialogToShow = null;
        final String packageName;
        final int userId;
        synchronized (mService) {
        
            //此处省略部分系统代码

			if(dialogToShow != null){// For don't show gaode-map <Stop running> dialog
			    Slog.w(TAG, "handleShowAppErrorUi ------------------");
			    if(proc != null && proc.info.packageName.equals("com.autonavi.amapauto")){
				    Slog.w(TAG, "Current app is gaode map, don't show <Stop running> dialog ------------------");
				    dialogToShow = null;
				    // Just kill the app if there is no dialog to be shown.
                    mService.killAppAtUsersRequest(proc, null);
			    }
		    }

        }
        // If we've created a crash dialog, show it without the lock held
        if (dialogToShow != null) {
            Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
			dialogToShow.show();
        }
    }

执行单编services.jar后推到机器,重启切换语言没有"高德地图已停止运行"弹窗了

3.后面考虑到高德地图用的公版,如果出现anr我们也得不到任何支援,所以把handleShowAnrUi和handleShowAppErrorUi两处屏蔽高德报错弹窗的代码都保留了,复盘方法名handleShowAnrUi明显就是应用出现anr时弹窗的位置。

总结:

絮絮叨叨的写这么多,实际是想更详尽的说明我解决问题的思路,套用前辈的一句话——编程是一种思维,编程思维需要慢慢培养。
所以我的博客都会详细的说明我的解决过程,过程中遇到了那些问题,遇到问题要怎么转换思路,大概如是……

-----------------------毕竟授人以鱼不如授人以渔。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值