前言
崩溃方法栈在ActivityThread中H(Handler)对象。由system_server进程通过binder发送过来的。
- 在onResume和onPause中注册/解注册BroadcastReceiver导致有几率出现上面崩溃,建议把BroadcastReceiver的注册放到onCreate和onDestory中。
- 使用LocalBroadcastManager来发送本地广播,如果监听的是系统广播,则没有办法使用
崩溃基本在API 30及以下机型,在Activity进入onPause生命周期后导致崩溃。
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
// 通过 binder 通知客户端,最后会触发对应的 Broadcast#onReceive() 方法回调
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
// DeadObjectException when the process isn't actually dead.
//} catch (DeadObjectException ex) {
// Failed to call into the process. It's dying so just let it die and move on.
// throw ex;
} catch (RemoteException ex) {
// 通过 binder 通知应用进程出现错误
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.pid + "). Crashing it.");
// 将广播错误的信息,通知给应用进程
app.scheduleCrash("can't deliver broadcast");
}
throw ex;
}
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
- 远端binder Service本身实现方法报错
- 通信本身中断导致报错