一、问题描述
android系统运行不正常的时候会弹出以下框框,需要手动选择。如果想取消弹框,直接关机运行不正常的应用,后台我们自己做守护程序。方法如下
本质是ANR对话框 是类class AppNotRespondingDialog在处理
[点击并拖拽以移动]
二、问题定位
点位弹框类在以下路径
base/services/core/java/com/android/server/am/AppNotRespondingDialog.java +110
关闭应用方法接口如下:
mService.killAppAtUsersRequest(proc, null);
怎么找到的如下红色字体:
130 @Override
131 public void onClick(View v) {
132 switch (v.getId()) {
133 case com.android.internal.R.id.aerr_report:
134 mHandler.obtainMessage(WAIT_AND_REPORT).sendToTarget();
135 break;
136 case com.android.internal.R.id.aerr_close:
137 mHandler.obtainMessage(FORCE_CLOSE).sendToTarget();
138 break;
139 case com.android.internal.R.id.aerr_wait:
140 mHandler.obtainMessage(WAIT).sendToTarget();
141 break;
142 default:
143 break;
144 }
145 }
private final Handler mHandler = new Handler() {
148 public void handleMessage(Message msg) {
149 Intent appErrorIntent = null;
150
151 MetricsLogger.action(getContext(), MetricsProto.MetricsEvent.ACTION_APP_ANR,
152 msg.what);
153
154 switch (msg.what) {
155 case FORCE_CLOSE:
156 // Kill the application.
157 mService.killAppAtUsersRequest(mProc, AppNotRespondingDialog.this);
158 break;
159 case WAIT_AND_REPORT:
160 case WAIT:
161 // Continue waiting for the application.
162 synchronized (mService) {
163 ProcessRecord app = mProc;
164
165 if (msg.what == WAIT_AND_REPORT) {
166 appErrorIntent = mService.mAppErrors.createAppErrorIntentLocked(app,
167 System.currentTimeMillis(), null);
168 }
169
170 app.notResponding = false;
171 app.notRespondingReport = null;
172 if (app.anrDialog == AppNotRespondingDialog.this) {
173 app.anrDialog = null;
174 }
175 mService.mServices.scheduleServiceTimeoutLocked(app);
176 }
177 break;
178 }
三、问题解决
搜索AppNotRespondingDialog ,发现在以下路径调用
base/services/core/java/com/android/server/am/AppErrors.java +955
分析代码:
1.不让框框弹出,直接kill应用。屏蔽红色代码,添加蓝色代码即可
950 void handleShowAnrUi(Message msg) {
951 Dialog d = null;
952 synchronized (mService) {
953 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
954 ProcessRecord proc = (ProcessRecord)data.get("app");
955 if (proc != null && proc.anrDialog != null) {
956 Slog.e(TAG, "App already has anr dialog: " + proc);
957 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
958 AppNotRespondingDialog.ALREADY_SHOWING);
959 return;
960 }
961
962 Intent intent = new Intent("android.intent.action.ANR");
963 if (!mService.mProcessesReady) {
964 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
965 | Intent.FLAG_RECEIVER_FOREGROUND);
966 }
967 mService.broadcastIntentLocked(null, null, intent,
968 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
969 null, false, false, MY_PID, Process.SYSTEM_UID, 0 / TODO: Verify /);
970
971 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
972 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
973 if (mService.canShowErrorDialogs() || showBackground) {
//我们修改的内容就在这里
974 mService.killAppAtUsersRequest(proc, null);
975 // d = new AppNotRespondingDialog(mService,
976 // mContext, proc, (ActivityRecord)data.get("activity"),
977 // msg.arg1 != 0);
978 //proc.anrDialog = d;
979 } else {
980 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
981 AppNotRespondingDialog.CANT_SHOW);
982 // Just kill the app if there is no dialog to be shown.
983 mService.killAppAtUsersRequest(proc, null);
984 }
985 }
986 // If we've created a crash dialog, show it without the lock held
987 if (d != null) { //
988 //d.closeAnrApp();
989 d.show();
990 }
991 }