深入理解 Android 9.0 Crash 机制 读懂底层原理 看清表面逻辑( 五 )


static ComponentName getErrorReportReceiver(PackageManager pm, String errorPackage, String receiverPackage) { if (receiverPackage == null || receiverPackage.length() == 0) { return null; } //当安装应用程序的安装器Crash , 则直接返回 if (receiverPackage.equals(errorPackage)) { return null; } //ACTION_APP_ERROR值为"android.intent.action.APP_ERROR" Intent intent = new Intent(Intent.ACTION_APP_ERROR); intent.setPackage(receiverPackage); ResolveInfo info = pm.resolveActivity(intent, 0); if (info == null || info.activityInfo == null) { return null; } //创建包名为receiverPackage的组件 return new ComponentName(receiverPackage, info.activityInfo.name); }【深入理解 Android 9.0 Crash 机制 读懂底层原理 看清表面逻辑】7.2 skipCurrentReceiverLocked
ActivityManagerService.java
忽略当前app的广播接收
void skipCurrentReceiverLocked(ProcessRecord app) { for (BroadcastQueue queue : mBroadcastQueues) { // 会调用BroadcastQueue 中的方法【见小节7.2.1】 queue.skipCurrentReceiverLocked(app); } }7.2.1 skipCurrentReceiverLocked
BroadcastQueue.java skipCurrentReceiverLocked忽略当前app的广播接收.
public void skipCurrentReceiverLocked(ProcessRecord app) { BroadcastRecord r = null; //查看app进程中的广播 if (mOrderedBroadcasts.size() > 0) { BroadcastRecord br = mOrderedBroadcasts.get(0); // 判断是否一致 if (br.curApp == app) { r = br; } } ... ... if (r != null) { // 见7.2.2 skipReceiverLocked(r); } }7.2.2 skipReceiverLocked
BroadcastQueue.java
private void skipReceiverLocked(BroadcastRecord r) { logBroadcastReceiverDiscardLocked(r); //结束app进程的广播结束 finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false); //执行广播调度 scheduleBroadcastsLocked(); }八、stopFreezingAllLocked处理分析AppError.java中的 makeAppCrashingLocked方法(第6步) , 会调用stopFreezingAllLocked 方法
ProcessRecord.java
public void stopFreezingAllLocked() { int i = activities.size(); while (i > 0) { i--; // 停止进程里所有的`Activity`. 详见8.1activities.get(i).stopFreezingScreenLocked(true); } }其中activities类型为ArrayList , 停止进程里所有的Activity.
8.1 AR.stopFreezingScreenLocked
ActivityRecord.java,stopFreezingScreenLocked停止进程里所有的Activity.
public void stopFreezingScreenLocked(boolean force) { if (force || frozenBeforeDestroy) { frozenBeforeDestroy = false; // mWindowContainerController 见【8.1.1】 mWindowContainerController.stopFreezingScreen(force); } }8.1.1mWindowContainerController.stopFreezingScreen
stopFreezingScreen.java
public void stopFreezingScreen(boolean force) { synchronized(mWindowMap) { if (mContainer == null) { return; } if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + mToken + ": hidden=" + mContainer.isHidden() + " freezing=" + mContainer.isFreezingScreen()); mContainer.stopFreezingScreen(true, force); } }8.1.1.1 WMS.stopFreezingScreenLocked
WindowManagerService.java
@Override public void stopFreezingScreen() { ... ... synchronized(mWindowMap) { if (mClientFreezingScreen) { mClientFreezingScreen = false; mLastFinishedFreezeSource = "client"; final long origId = Binder.clearCallingIdentity(); try { // 详见 8.1.1.2 stopFreezingDisplayLocked(); } finally { Binder.restoreCallingIdentity(origId); } } } }8.1.1.2 stopFreezingDisplayLocked();
WindowManagerService.java
该方法主要功能:
处理屏幕旋转相关逻辑;
移除冻屏的超时消息;
屏幕旋转动画的相关操作;
使能输入事件分发功能;
display冻结时 , 执行gc操作;
更新当前的屏幕方向;
向mH发送configuraion改变的消息
rivate void stopFreezingDisplayLocked() { if (!mDisplayFrozen) { return; //显示没有冻结 , 则直接返回 } //往往跟屏幕旋转相关 ... mDisplayFrozen = false; //从上次冻屏到现在的总时长 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime); //移除冻屏的超时消息 mH.removeMessages(H.APP_FREEZE_TIMEOUT); mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); boolean updateRotation = false; //获取默认的DisplayContent final DisplayContent displayContent = getDefaultDisplayContentLocked(); final int displayId = displayContent.getDisplayId(); ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId); //屏幕旋转动画的相关操作 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) { DisplayInfo displayInfo = displayContent.getDisplayInfo(); boolean isDimming = displayContent.isDimming(); if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) { mExitAnimId = mEnterAnimId = 0; } //加载动画最大时长为10s if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) { scheduleAnimationLocked(); } else { screenRotationAnimation.kill(); mAnimator.setScreenRotationAnimationLocked(displayId, null); updateRotation = true; } } else { if (screenRotationAnimation != null) { screenRotationAnimation.kill(); mAnimator.setScreenRotationAnimationLocked(displayId, null); } updateRotation = true; } //经过层层调用到InputManagerService服务 , IMS服务使能输入事件分发功能 mInputMonitor.thawInputDispatchingLw(); boolean configChanged; //当display被冻结时不再计算屏幕方向 , 以避免不连续的状态 。configChanged = updateOrientationFromAppTokensLocked(false); //display冻结时 , 执行gc操作 mH.removeMessages(H.FORCE_GC); mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000); //mScreenFrozenLock的类型为PowerManager.WakeLock , 即释放屏幕冻结的锁 mScreenFrozenLock.release(); if (updateRotation) { //更新当前的屏幕方向 configChanged |= updateRotationUncheckedLocked(false); } if (configChanged) { //向mH发送configuraion改变的消息 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); }}


推荐阅读