Android Make sure other views do not use the same id. 错误解决

解决Android View组件的onRestoreInstanceState异常问题
本文提供了解决Android应用中特定View组件在onRestoreInstanceState方法中出现异常的解决方案,通过重写该方法并适当地处理状态恢复过程,确保应用在设备旋转或其他配置变化后能够正确地恢复视图状态。

解决方案:

在出现这种情况的View  中 重写 onRestoreInstanceState方法


详细代码:

	protected void onRestoreInstanceState(Parcelable state) {
		try {
			super.onRestoreInstanceState(state);
		} catch (Exception e) {
		}
		state = null;
	}

Fatal Exception: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class androidx.appcompat.widget.Toolbar$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/toolbar. Make sure other views do not use the same id. at android.view.View.onRestoreInstanceState(View.java:21043) at android.view.View.dispatchRestoreInstanceState(View.java:21015) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4063) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4069) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4069) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4069) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4069) at android.view.View.restoreHierarchyState(View.java:20993) at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2185) at android.app.Activity.onRestoreInstanceState(Activity.java:1753) at android.app.Activity.performRestoreInstanceState(Activity.java:1706) at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1356) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3618) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2187) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:8057) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011) 线上崩溃分析
07-02
private void performTraversals() { 3295 mLastPerformTraversalsSkipDrawReason = null; 3296 3297 // cache mView since it is used so much below... 3298 final View host = mView; 3299 if (DBG) { 3300 System.out.println("======================================"); 3301 System.out.println("performTraversals"); 3302 host.debug(); 3303 } 3304 3305 if (host == null || !mAdded) { 3306 mLastPerformTraversalsSkipDrawReason = host == null ? "no_host" : "not_added"; 3307 return; 3308 } 3309 3310 if (mNumPausedForSync > 0) { 3311 if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { 3312 Trace.instant(Trace.TRACE_TAG_VIEW, 3313 TextUtils.formatSimple("performTraversals#mNumPausedForSync=%d", 3314 mNumPausedForSync)); 3315 } 3316 3317 Log.d(mTag, "Skipping traversal due to sync " + mNumPausedForSync); 3318 mLastPerformTraversalsSkipDrawReason = "paused_for_sync"; 3319 return; 3320 } 3321 3322 // #ifdef OPLUS_FEATURE_VIEW_DEBUG 3323 // Bard.Zhang@Android.UIFramework 2023-01-28 Add for : view debug 3324 mViewRootImplExt.markOnPerformTraversalsStart(host, mFirst); 3325 // #endif /* OPLUS_FEATURE_VIEW_DEBUG */ 3326 3327 mIsInTraversal = true; 3328 mWillDrawSoon = true; 3329 boolean cancelDraw = false; 3330 String cancelReason = null; 3331 boolean isSyncRequest = false; 3332 3333 boolean windowSizeMayChange = false; 3334 WindowManager.LayoutParams lp = mWindowAttributes; 3335 3336 int desiredWindowWidth; 3337 int desiredWindowHeight; 3338 3339 final int viewVisibility = getHostVisibility(); 3340 final boolean viewVisibilityChanged = !mFirst 3341 && (mViewVisibility != viewVisibility || mNewSurfaceNeeded 3342 // Also check for possible double visibility update, which will make current 3343 // viewVisibility value equal to mViewVisibility and we may miss it. 3344 || mAppVisibilityChanged); 3345 mAppVisibilityChanged = false; 3346 final boolean viewUserVisibilityChanged = !mFirst && 3347 ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE)); 3348 final boolean shouldOptimizeMeasure = shouldOptimizeMeasure(lp); 3349 3350 WindowManager.LayoutParams params = null; 3351 CompatibilityInfo compatibilityInfo = 3352 mDisplay.getDisplayAdjustments().getCompatibilityInfo(); 3353 if (compatibilityInfo.supportsScreen() == mLastInCompatMode) { 3354 params = lp; 3355 mFullRedrawNeeded = true; 3356 mLayoutRequested = true; 3357 if (mLastInCompatMode) { 3358 params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 3359 mLastInCompatMode = false; 3360 } else { 3361 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 3362 mLastInCompatMode = true; 3363 } 3364 } 3365 3366 Rect frame = mWinFrame; 3367 if (mFirst) { 3368 mFullRedrawNeeded = true; 3369 mLayoutRequested = true; 3370 3371 final Configuration config = getConfiguration(); 3372 if (shouldUseDisplaySize(lp)) { 3373 // NOTE -- system code, won't try to do compat mode. 3374 Point size = new Point(); 3375 mDisplay.getRealSize(size); 3376 desiredWindowWidth = size.x; 3377 desiredWindowHeight = size.y; 3378 } else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT 3379 || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 3380 // For wrap content, we have to remeasure later on anyways. Use size consistent with 3381 // below so we get best use of the measure cache. 3382 final Rect bounds = getWindowBoundsInsetSystemBars(); 3383 desiredWindowWidth = bounds.width(); 3384 desiredWindowHeight = bounds.height(); 3385 } else { 3386 // After addToDisplay, the frame contains the frameHint from window manager, which 3387 // for most windows is going to be the same size as the result of relayoutWindow. 3388 // Using this here allows us to avoid remeasuring after relayoutWindow 3389 desiredWindowWidth = frame.width(); 3390 desiredWindowHeight = frame.height(); 3391 } 3392 3393 // We used to use the following condition to choose 32 bits drawing caches: 3394 // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888 3395 // However, windows are now always 32 bits by default, so choose 32 bits 3396 mAttachInfo.mUse32BitDrawingCache = true; 3397 mAttachInfo.mWindowVisibility = viewVisibility; 3398 mAttachInfo.mRecomputeGlobalAttributes = false; 3399 mLastConfigurationFromResources.setTo(config); 3400 mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; 3401 // Set the layout direction if it has not been set before (inherit is the default) 3402 if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) { 3403 host.setLayoutDirection(config.getLayoutDirection()); 3404 } 3405 //#ifdef OPLUS_FEATURE_BRACKETMODE_2_0 3406 //wenguangyu@ANDROID.WMS, 2022/10/02, add for bracket mode 3407 mViewRootImplExt.attachToWindow(); 3408 //#endif /*OPLUS_FEATURE_BRACKETMODE_2_0*/ 3409 host.dispatchAttachedToWindow(mAttachInfo, 0); 3410 mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true); 3411 dispatchApplyInsets(host); 3412 if (!mOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled()) { 3413 // For apps requesting legacy back behavior, we add a compat callback that 3414 // dispatches {@link KeyEvent#KEYCODE_BACK} to their root views. 3415 // This way from system point of view, these apps are providing custom 3416 // {@link OnBackInvokedCallback}s, and will not play system back animations 3417 // for them. 3418 registerCompatOnBackInvokedCallback(); 3419 } 3420 } else { 3421 desiredWindowWidth = frame.width(); 3422 desiredWindowHeight = frame.height(); 3423 if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) { 3424 if (DEBUG_ORIENTATION) Log.v(mTag, "View " + host + " resized to: " + frame); 3425 mFullRedrawNeeded = true; 3426 mLayoutRequested = true; 3427 windowSizeMayChange = true; 3428 } 3429 } 3430 3431 if (viewVisibilityChanged) { 3432 mAttachInfo.mWindowVisibility = viewVisibility; 3433 host.dispatchWindowVisibilityChanged(viewVisibility); 3434 mAttachInfo.mTreeObserver.dispatchOnWindowVisibilityChange(viewVisibility); 3435 if (viewUserVisibilityChanged) { 3436 host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE); 3437 } 3438 if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) { 3439 endDragResizing(); 3440 destroyHardwareResources(); 3441 } 3442 } 3443 3444 // Non-visible windows can't hold accessibility focus. 3445 if (mAttachInfo.mWindowVisibility != View.VISIBLE) { 3446 host.clearAccessibilityFocus(); 3447 } 3448 3449 // Execute enqueued actions on every traversal in case a detached view enqueued an action 3450 getRunQueue().executeActions(mAttachInfo.mHandler); 3451 3452 if (mFirst) { 3453 // make sure touch mode code executes by setting cached value 3454 // to opposite of the added touch mode. 3455 mAttachInfo.mInTouchMode = !mAddedTouchMode; 3456 ensureTouchModeLocally(mAddedTouchMode); 3457 } 3458 3459 boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw); 3460 if (layoutRequested) { 3461 if (!mFirst) { 3462 if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT 3463 || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 3464 windowSizeMayChange = true; 3465 3466 if (shouldUseDisplaySize(lp)) { 3467 // NOTE -- system code, won't try to do compat mode. 3468 Point size = new Point(); 3469 mDisplay.getRealSize(size); 3470 desiredWindowWidth = size.x; 3471 desiredWindowHeight = size.y; 3472 } else { 3473 final Rect bounds = getWindowBoundsInsetSystemBars(); 3474 desiredWindowWidth = bounds.width(); 3475 desiredWindowHeight = bounds.height(); 3476 } 3477 } 3478 } 3479 3480 // Ask host how big it wants to be 3481 windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(), 3482 desiredWindowWidth, desiredWindowHeight, shouldOptimizeMeasure); 3483 } 3484 3485 if (collectViewAttributes()) { 3486 params = lp; 3487 } 3488 if (mAttachInfo.mForceReportNewAttributes) { 3489 mAttachInfo.mForceReportNewAttributes = false; 3490 params = lp; 3491 } 3492 3493 if (mFirst || mAttachInfo.mViewVisibilityChanged) { 3494 mAttachInfo.mViewVisibilityChanged = false; 3495 int resizeMode = mSoftInputMode & SOFT_INPUT_MASK_ADJUST; 3496 // If we are in auto resize mode, then we need to determine 3497 // what mode to use now. 3498 if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) { 3499 final int N = mAttachInfo.mScrollContainers.size(); 3500 for (int i=0; i<N; i++) { 3501 if (mAttachInfo.mScrollContainers.get(i).isShown()) { 3502 resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 3503 } 3504 } 3505 if (resizeMode == 0) { 3506 resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; 3507 } 3508 if ((lp.softInputMode & SOFT_INPUT_MASK_ADJUST) != resizeMode) { 3509 lp.softInputMode = (lp.softInputMode & ~SOFT_INPUT_MASK_ADJUST) | resizeMode; 3510 params = lp; 3511 } 3512 } 3513 } 3514 3515 if (mApplyInsetsRequested) { 3516 dispatchApplyInsets(host); 3517 if (mLayoutRequested) { 3518 // Short-circuit catching a new layout request here, so 3519 // we don't need to go through two layout passes when things 3520 // change due to fitting system windows, which can happen a lot. 3521 windowSizeMayChange |= measureHierarchy(host, lp, 3522 mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight, 3523 shouldOptimizeMeasure); 3524 } 3525 } 3526 3527 if (layoutRequested) { 3528 // Clear this now, so that if anything requests a layout in the 3529 // rest of this function we will catch it and re-run a full 3530 // layout pass. 3531 mLayoutRequested = false; 3532 } 3533 3534 boolean windowShouldResize = layoutRequested && windowSizeMayChange 3535 && ((mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) 3536 || (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT && 3537 frame.width() < desiredWindowWidth && frame.width() != mWidth) 3538 || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT && 3539 frame.height() < desiredWindowHeight && frame.height() != mHeight)); 3540 windowShouldResize |= mDragResizing && mPendingDragResizing; 3541 3542 // Determine whether to compute insets. 3543 // If there are no inset listeners remaining then we may still need to compute 3544 // insets in case the old insets were non-empty and must be reset. 3545 final boolean computesInternalInsets = 3546 mAttachInfo.mTreeObserver.hasComputeInternalInsetsListeners() 3547 || mAttachInfo.mHasNonEmptyGivenInternalInsets; 3548 3549 boolean insetsPending = false; 3550 int relayoutResult = 0; 3551 boolean updatedConfiguration = false; 3552 3553 final int surfaceGenerationId = mSurface.getGenerationId(); 3554 3555 final boolean isViewVisible = viewVisibility == View.VISIBLE; 3556 boolean surfaceSizeChanged = false; 3557 boolean surfaceCreated = false; 3558 boolean surfaceDestroyed = false; 3559 // True if surface generation id changes or relayout result is RELAYOUT_RES_SURFACE_CHANGED. 3560 boolean surfaceReplaced = false; 3561 3562 final boolean windowAttributesChanged = mWindowAttributesChanged; 3563 if (windowAttributesChanged) { 3564 mWindowAttributesChanged = false; 3565 params = lp; 3566 } 3567 3568 if (params != null) { 3569 if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0 3570 && !PixelFormat.formatHasAlpha(params.format)) { 3571 params.format = PixelFormat.TRANSLUCENT; 3572 } 3573 adjustLayoutParamsForCompatibility(params); 3574 controlInsetsForCompatibility(params); 3575 if (mDispatchedSystemBarAppearance != params.insetsFlags.appearance) { 3576 mDispatchedSystemBarAppearance = params.insetsFlags.appearance; 3577 mView.onSystemBarAppearanceChanged(mDispatchedSystemBarAppearance); 3578 } 3579 } 3580 3581 if (mFirst || windowShouldResize || viewVisibilityChanged || params != null 3582 || mForceNextWindowRelayout) { 3583 if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { 3584 Trace.traceBegin(Trace.TRACE_TAG_VIEW, 3585 TextUtils.formatSimple("relayoutWindow#" 3586 + "first=%b/resize=%b/vis=%b/params=%b/force=%b", 3587 mFirst, windowShouldResize, viewVisibilityChanged, params != null, 3588 mForceNextWindowRelayout)); 3589 } 3590 3591 mForceNextWindowRelayout = false; 3592 3593 // If this window is giving internal insets to the window manager, then we want to first 3594 // make the provided insets unchanged during layout. This avoids it briefly causing 3595 // other windows to resize/move based on the raw frame of the window, waiting until we 3596 // can finish laying out this window and get back to the window manager with the 3597 // ultimately computed insets. 3598 insetsPending = computesInternalInsets; 3599 3600 if (mSurfaceHolder != null) { 3601 mSurfaceHolder.mSurfaceLock.lock(); 3602 mDrawingAllowed = true; 3603 } 3604 3605 boolean hwInitialized = false; 3606 boolean dispatchApplyInsets = false; 3607 boolean hadSurface = mSurface.isValid(); 3608 3609 try { 3610 if (DEBUG_LAYOUT) { 3611 Log.i(mTag, "host=w:" + host.getMeasuredWidth() + ", h:" + 3612 host.getMeasuredHeight() + ", params=" + params); 3613 } 3614 3615 if (mFirst || viewVisibilityChanged) { 3616 mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED; 3617 } 3618 //#ifdef OPLUS_FEATURE_JANK_TRACKER 3619 //wangwei11@oppo.com, 2021/11/28, Add for janktracker 3620 mChoreographer.mChoreographerExt.markRelayout(); 3621 //#endif /*OPLUS_FEATURE_JANK_TRACKER*/ 3622 relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); 3623 cancelDraw = (relayoutResult & RELAYOUT_RES_CANCEL_AND_REDRAW) 3624 == RELAYOUT_RES_CANCEL_AND_REDRAW; 3625 cancelReason = "relayout"; 3626 final boolean dragResizing = mPendingDragResizing; 3627 if (mSyncSeqId > mLastSyncSeqId) { 3628 mLastSyncSeqId = mSyncSeqId; 3629 if (DEBUG_BLAST) { 3630 Log.d(mTag, "Relayout called with blastSync"); 3631 } 3632 reportNextDraw("relayout"); 3633 mSyncBuffer = true; 3634 isSyncRequest = true; 3635 if (!cancelDraw) { 3636 mDrewOnceForSync = false; 3637 } 3638 } 3639 3640 final boolean surfaceControlChanged = 3641 (relayoutResult & RELAYOUT_RES_SURFACE_CHANGED) 3642 == RELAYOUT_RES_SURFACE_CHANGED; 3643 3644 if (mSurfaceControl.isValid()) { 3645 updateOpacity(mWindowAttributes, dragResizing, 3646 surfaceControlChanged /*forceUpdate */); 3647 // No need to updateDisplayDecoration if it's a new SurfaceControl and 3648 // mDisplayDecorationCached is false, since that's the default for a new 3649 // SurfaceControl. 3650 if (surfaceControlChanged && mDisplayDecorationCached) { 3651 updateDisplayDecoration(); 3652 } 3653 if (surfaceControlChanged 3654 && mWindowAttributes.type 3655 == WindowManager.LayoutParams.TYPE_STATUS_BAR) { 3656 mTransaction.setDefaultFrameRateCompatibility(mSurfaceControl, 3657 Surface.FRAME_RATE_COMPATIBILITY_NO_VOTE).apply(); 3658 } 3659 } 3660 3661 if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString() 3662 + " surface=" + mSurface); 3663 3664 // If the pending {@link MergedConfiguration} handed back from 3665 // {@link #relayoutWindow} does not match the one last reported, 3666 // WindowManagerService has reported back a frame from a configuration not yet 3667 // handled by the client. In this case, we need to accept the configuration so we 3668 // do not lay out and draw with the wrong configuration. 3669 if (mRelayoutRequested 3670 && !mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) { 3671 if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: " 3672 + mPendingMergedConfiguration.getMergedConfiguration()); 3673 performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration), 3674 !mFirst, INVALID_DISPLAY /* same display */); 3675 updatedConfiguration = true; 3676 } 3677 final boolean updateSurfaceNeeded = mUpdateSurfaceNeeded; 3678 mUpdateSurfaceNeeded = false; 3679 3680 surfaceSizeChanged = false; 3681 if (!mLastSurfaceSize.equals(mSurfaceSize)) { 3682 surfaceSizeChanged = true; 3683 mLastSurfaceSize.set(mSurfaceSize.x, mSurfaceSize.y); 3684 } 3685 final boolean alwaysConsumeSystemBarsChanged = 3686 mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars; 3687 updateColorModeIfNeeded(lp.getColorMode()); 3688 surfaceCreated = !hadSurface && mSurface.isValid(); 3689 surfaceDestroyed = hadSurface && !mSurface.isValid(); 3690 3691 // When using Blast, the surface generation id may not change when there's a new 3692 // SurfaceControl. In that case, we also check relayout flag 3693 // RELAYOUT_RES_SURFACE_CHANGED since it should indicate that WMS created a new 3694 // SurfaceControl. 3695 surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId() 3696 || surfaceControlChanged) && mSurface.isValid(); 3697 if (surfaceReplaced) { 3698 mSurfaceSequenceId++; 3699 } 3700 if (alwaysConsumeSystemBarsChanged) { 3701 mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; 3702 dispatchApplyInsets = true; 3703 } 3704 if (updateCaptionInsets()) { 3705 dispatchApplyInsets = true; 3706 } 3707 if (dispatchApplyInsets || mLastSystemUiVisibility != 3708 mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested) { 3709 mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; 3710 dispatchApplyInsets(host); 3711 // We applied insets so force contentInsetsChanged to ensure the 3712 // hierarchy is measured below. 3713 dispatchApplyInsets = true; 3714 } 3715 3716 if (surfaceCreated) { 3717 // If we are creating a new surface, then we need to 3718 // completely redraw it. 3719 mFullRedrawNeeded = true; 3720 mPreviousTransparentRegion.setEmpty(); 3721 3722 // Only initialize up-front if transparent regions are not 3723 // requested, otherwise defer to see if the entire window 3724 // will be transparent 3725 if (mAttachInfo.mThreadedRenderer != null) { 3726 try { 3727 hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface); 3728 // #ifdef OPLUS_EXTENSION_HOOK 3729 // yanliang@Android.Performance 2023-02-13 Add for Optimize sliding effect 3730 mViewRootImplExt.setPendingBufferCountSetting(true); 3731 // #endif /*OPLUS_EXTENSION_HOOK*/ 3732 if (hwInitialized && (host.mPrivateFlags 3733 //#ifndef OPLUS_BUG_STABILITY 3734 //Weitao.Chen@ANDROID.STABILITY.2742412, 2020/01/02, Add for null pointer exp 3735 //& View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) { 3736 //#else 3737 & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0 && mAttachInfo.mThreadedRenderer != null) { 3738 //#endif /*OPLUS_BUG_STABILITY*/ 3739 // Don't pre-allocate if transparent regions 3740 // are requested as they may not be needed 3741 mAttachInfo.mThreadedRenderer.allocateBuffers(); 3742 } 3743 } catch (OutOfResourcesException e) { 3744 handleOutOfResourcesException(e); 3745 mLastPerformTraversalsSkipDrawReason = "oom_initialize_renderer"; 3746 return; 3747 } 3748 } 3749 } else if (surfaceDestroyed) { 3750 // If the surface has been removed, then reset the scroll 3751 // positions. 3752 if (mLastScrolledFocus != null) { 3753 mLastScrolledFocus.clear(); 3754 } 3755 mScrollY = mCurScrollY = 0; 3756 if (mView instanceof RootViewSurfaceTaker) { 3757 ((RootViewSurfaceTaker) mView).onRootViewScrollYChanged(mCurScrollY); 3758 } 3759 if (mScroller != null) { 3760 mScroller.abortAnimation(); 3761 } 3762 // Our surface is gone 3763 if (isHardwareEnabled()) { 3764 mAttachInfo.mThreadedRenderer.destroy(); 3765 } 3766 } else if ((surfaceReplaced || surfaceSizeChanged || updateSurfaceNeeded) 3767 && mSurfaceHolder == null 3768 && mAttachInfo.mThreadedRenderer != null 3769 && mSurface.isValid()) { 3770 mFullRedrawNeeded = true; 3771 try { 3772 // Need to do updateSurface (which leads to CanvasContext::setSurface and 3773 // re-create the EGLSurface) if either the Surface changed (as indicated by 3774 // generation id), or WindowManager changed the surface size. The latter is 3775 // because on some chips, changing the consumer side's BufferQueue size may 3776 // not take effect immediately unless we create a new EGLSurface. 3777 // Note that frame size change doesn't always imply surface size change (eg. 3778 // drag resizing uses fullscreen surface), need to check surfaceSizeChanged 3779 // flag from WindowManager. 3780 mAttachInfo.mThreadedRenderer.updateSurface(mSurface); 3781 } catch (OutOfResourcesException e) { 3782 handleOutOfResourcesException(e); 3783 mLastPerformTraversalsSkipDrawReason = "oom_update_surface"; 3784 return; 3785 } 3786 } 3787 3788 if (mDragResizing != dragResizing) { 3789 if (dragResizing) { 3790 final boolean backdropSizeMatchesFrame = 3791 mWinFrame.width() == mPendingBackDropFrame.width() 3792 && mWinFrame.height() == mPendingBackDropFrame.height(); 3793 // TODO: Need cutout? 3794 startDragResizing(mPendingBackDropFrame, !backdropSizeMatchesFrame, 3795 mAttachInfo.mContentInsets, mAttachInfo.mStableInsets); 3796 } else { 3797 // We shouldn't come here, but if we come we should end the resize. 3798 endDragResizing(); 3799 } 3800 } 3801 if (!mUseMTRenderer) { 3802 if (dragResizing) { 3803 mCanvasOffsetX = mWinFrame.left; 3804 mCanvasOffsetY = mWinFrame.top; 3805 } else { 3806 mCanvasOffsetX = mCanvasOffsetY = 0; 3807 } 3808 } 3809 } catch (RemoteException e) { 3810 } finally { 3811 if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { 3812 Trace.traceEnd(Trace.TRACE_TAG_VIEW); 3813 } 3814 } 3815 3816 if (DEBUG_ORIENTATION) Log.v( 3817 TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface); 3818 3819 mAttachInfo.mWindowLeft = frame.left; 3820 mAttachInfo.mWindowTop = frame.top; 3821 3822 // !!FIXME!! This next section handles the case where we did not get the 3823 // window size we asked for. We should avoid this by getting a maximum size from 3824 // the window session beforehand. 3825 if (mWidth != frame.width() || mHeight != frame.height()) { 3826 mWidth = frame.width(); 3827 mHeight = frame.height(); 3828 } 3829 3830 if (mSurfaceHolder != null) { 3831 // The app owns the surface; tell it about what is going on. 3832 if (mSurface.isValid()) { 3833 // XXX .copyFrom() doesn't work! 3834 //mSurfaceHolder.mSurface.copyFrom(mSurface); 3835 mSurfaceHolder.mSurface = mSurface; 3836 } 3837 mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight); 3838 mSurfaceHolder.mSurfaceLock.unlock(); 3839 if (surfaceCreated) { 3840 mSurfaceHolder.ungetCallbacks(); 3841 3842 mIsCreating = true; 3843 SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks(); 3844 if (callbacks != null) { 3845 for (SurfaceHolder.Callback c : callbacks) { 3846 c.surfaceCreated(mSurfaceHolder); 3847 } 3848 } 3849 } 3850 3851 if ((surfaceCreated || surfaceReplaced || surfaceSizeChanged 3852 || windowAttributesChanged) && mSurface.isValid()) { 3853 SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks(); 3854 if (callbacks != null) { 3855 for (SurfaceHolder.Callback c : callbacks) { 3856 c.surfaceChanged(mSurfaceHolder, lp.format, 3857 mWidth, mHeight); 3858 } 3859 } 3860 mIsCreating = false; 3861 } 3862 3863 if (surfaceDestroyed) { 3864 notifyHolderSurfaceDestroyed(); 3865 mSurfaceHolder.mSurfaceLock.lock(); 3866 try { 3867 mSurfaceHolder.mSurface = new Surface(); 3868 } finally { 3869 mSurfaceHolder.mSurfaceLock.unlock(); 3870 } 3871 } 3872 } 3873 3874 final ThreadedRenderer threadedRenderer = mAttachInfo.mThreadedRenderer; 3875 if (threadedRenderer != null && threadedRenderer.isEnabled()) { 3876 if (hwInitialized 3877 || mWidth != threadedRenderer.getWidth() 3878 || mHeight != threadedRenderer.getHeight() 3879 || mNeedsRendererSetup) { 3880 threadedRenderer.setup(mWidth, mHeight, mAttachInfo, 3881 mWindowAttributes.surfaceInsets); 3882 mNeedsRendererSetup = false; 3883 } 3884 } 3885 3886 // TODO: In the CL "ViewRootImpl: Fix issue with early draw report in 3887 // seamless rotation". We moved processing of RELAYOUT_RES_BLAST_SYNC 3888 // earlier in the function, potentially triggering a call to 3889 // reportNextDraw(). That same CL changed this and the next reference 3890 // to wasReportNextDraw, such that this logic would remain undisturbed 3891 // (it continues to operate as if the code was never moved). This was 3892 // done to achieve a more hermetic fix for S, but it's entirely 3893 // possible that checking the most recent value is actually more 3894 // correct here. 3895 if (!mStopped || mReportNextDraw) { 3896 if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() 3897 || dispatchApplyInsets || updatedConfiguration) { 3898 int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width, 3899 lp.privateFlags); 3900 int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height, 3901 lp.privateFlags); 3902 3903 if (DEBUG_LAYOUT) Log.v(mTag, "Ooops, something changed! mWidth=" 3904 + mWidth + " measuredWidth=" + host.getMeasuredWidth() 3905 + " mHeight=" + mHeight 3906 + " measuredHeight=" + host.getMeasuredHeight() 3907 + " dispatchApplyInsets=" + dispatchApplyInsets); 3908 3909 // #ifdef OPLUS_FEATURE_VIEW_DEBUG 3910 // Bard.Zhang@Android.UIFramework 2023-01-19 Add for : view debug 3911 String measureReason = "Measure reason mFirst " + mFirst 3912 + " windowShouldResize " + windowShouldResize 3913 + " viewVisibilityChanged " + viewVisibilityChanged 3914 + " params != null " + (params != null) 3915 + " mForceNextWindowRelayout " + mForceNextWindowRelayout 3916 + " mStopped " + mStopped + " mReportNextDraw " + mReportNextDraw 3917 + " mWidth " + mWidth + " host.getMeasuredWidth " + host.getMeasuredWidth() 3918 + " mHeight " + mHeight + " host.getMeasuredHeight " + host.getMeasuredHeight() 3919 + " dispatchApplyInsets " + dispatchApplyInsets 3920 + " updateConfiguration " + updatedConfiguration; 3921 mViewRootImplExt.markPerformMeasureReason(measureReason); 3922 // #endif /* OPLUS_FEATURE_VIEW_DEBUG */ 3923 // #ifdef OPLUS_BUG_COMPATIBILITY 3924 //Qian.Jiang@Android.Wms, 2023/05/19: fix bug-5573936 3925 int heightMesure = MeasureSpec.getSize(childHeightMeasureSpec); 3926 int widthMesure = MeasureSpec.getSize(childWidthMeasureSpec); 3927 if (PANIC_DEBUG && (heightMesure > LIMIT || widthMesure > LIMIT)) { 3928 Log.d(mTag, "performMeasure heightMesure = " + heightMesure + ",widthMesure = " + widthMesure); 3929 } 3930 //#endif /* OPLUS_BUG_COMPATIBILITY */ 3931 // Ask host how big it wants to be 3932 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); 3933 3934 // Implementation of weights from WindowManager.LayoutParams 3935 // We just grow the dimensions as needed and re-measure if 3936 // needs be 3937 int width = host.getMeasuredWidth(); 3938 int height = host.getMeasuredHeight(); 3939 boolean measureAgain = false; 3940 3941 if (lp.horizontalWeight > 0.0f) { 3942 width += (int) ((mWidth - width) * lp.horizontalWeight); 3943 childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, 3944 MeasureSpec.EXACTLY); 3945 measureAgain = true; 3946 } 3947 if (lp.verticalWeight > 0.0f) { 3948 height += (int) ((mHeight - height) * lp.verticalWeight); 3949 childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, 3950 MeasureSpec.EXACTLY); 3951 measureAgain = true; 3952 } 3953 3954 if (measureAgain) { 3955 if (DEBUG_LAYOUT) Log.v(mTag, 3956 "And hey let's measure once more: width=" + width 3957 + " height=" + height); 3958 3959 // #ifdef OPLUS_FEATURE_VIEW_DEBUG 3960 // Bard.Zhang@Android.UIFramework 2023-01-19 Add for : view debug 3961 mMeasureReason = "3"; 3962 String measureAgainReason = "Measure again lp.horizontalWeight " + lp.horizontalWeight 3963 + " lp.verticalWeight " + lp.verticalWeight; 3964 mViewRootImplExt.markPerformMeasureReason(measureAgainReason); 3965 // #endif /* OPLUS_FEATURE_VIEW_DEBUG */ 3966 3967 // #ifdef OPLUS_BUG_COMPATIBILITY 3968 //Qian.Jiang@Android.Wms, 2023/05/19: fix bug-5573936 3969 int heightAgain = MeasureSpec.getSize(childHeightMeasureSpec); 3970 int widthAgain = MeasureSpec.getSize(childWidthMeasureSpec); 3971 if (PANIC_DEBUG && (heightAgain > LIMIT || widthAgain > LIMIT)) { 3972 Log.d(mTag, "measureAgain performMeasure heightAgain = " + heightAgain + ",widthAgain = " + widthAgain); 3973 } 3974 //#endif /* OPLUS_BUG_COMPATIBILITY */ 3975 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); 3976 } 3977 3978 layoutRequested = true; 3979 } 3980 } 3981 } else { 3982 // Not the first pass and no window/insets/visibility change but the window 3983 // may have moved and we need check that and if so to update the left and right 3984 // in the attach info. We translate only the window frame since on window move 3985 // the window manager tells us only for the new frame but the insets are the 3986 // same and we do not want to translate them more than once. 3987 maybeHandleWindowMove(frame); 3988 } 3989 3990 if (mViewMeasureDeferred) { 3991 // It's time to measure the views since we are going to layout them. 3992 performMeasure( 3993 MeasureSpec.makeMeasureSpec(frame.width(), MeasureSpec.EXACTLY), 3994 MeasureSpec.makeMeasureSpec(frame.height(), MeasureSpec.EXACTLY)); 3995 } 3996 3997 if (!mRelayoutRequested && mCheckIfCanDraw) { 3998 // We had a sync previously, but we didn't call IWindowSession#relayout in this 3999 // traversal. So we don't know if the sync is complete that we can continue to draw. 4000 // Here invokes cancelDraw to obtain the information. 4001 try { 4002 cancelDraw = mWindowSession.cancelDraw(mWindow); 4003 cancelReason = "wm_sync"; 4004 Log.d(mTag, "cancelDraw returned " + cancelDraw); 4005 } catch (RemoteException e) { 4006 } 4007 } 4008 4009 if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || 4010 windowAttributesChanged || mChildBoundingInsetsChanged) { 4011 // If the surface has been replaced, there's a chance the bounds layer is not parented 4012 // to the new layer. When updating bounds layer, also reparent to the main VRI 4013 // SurfaceControl to ensure it's correctly placed in the hierarchy. 4014 // 4015 // This needs to be done on the client side since WMS won't reparent the children to the 4016 // new surface if it thinks the app is closing. WMS gets the signal that the app is 4017 // stopping, but on the client side it doesn't get stopped since it's restarted quick 4018 // enough. WMS doesn't want to keep around old children since they will leak when the 4019 // client creates new children. 4020 prepareSurfaces(); 4021 mChildBoundingInsetsChanged = false; 4022 } 4023 4024 final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw); 4025 boolean triggerGlobalLayoutListener = didLayout 4026 || mAttachInfo.mRecomputeGlobalAttributes; 4027 if (didLayout) { 4028 //#ifdef OPLUS_EXTENSION_HOOK 4029 //Jie.Zhang@ANDROID.PERFORMANCE, 2021/12/14, Add for quality information update 4030 final long startTime = SystemClock.uptimeMillis(); 4031 performLayout(lp, mWidth, mHeight); 4032 ExtLoader.type(IOplusJankMonitorExt.class).create().setLaunchStageTime(ActivityThread.currentProcessName(), "performLayout", startTime); 4033 //#endif /* OPLUS_EXTENSION_HOOK */ 4034 // #ifdef OPLUS_EXTENSION_HOOK 4035 // Guofu.Yang@ANDROID.WMS, 2018/02/23, [OSP-1634] add for Screen mode. 4036 mViewRootImplExt.setRefreshRateIfNeed((mView instanceof ViewGroup), mContext, 4037 mView, mWindow); 4038 // #endif /* OPLUS_EXTENSION_HOOK */ 4039 4040 // By this point all views have been sized and positioned 4041 // We can compute the transparent area 4042 4043 if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { 4044 // start out transparent 4045 // TODO: AVOID THAT CALL BY CACHING THE RESULT? 4046 host.getLocationInWindow(mTmpLocation); 4047 mTransparentRegion.set(mTmpLocation[0], mTmpLocation[1], 4048 mTmpLocation[0] + host.mRight - host.mLeft, 4049 mTmpLocation[1] + host.mBottom - host.mTop); 4050 4051 host.gatherTransparentRegion(mTransparentRegion); 4052 if (mTranslator != null) { 4053 mTranslator.translateRegionInWindowToScreen(mTransparentRegion); 4054 } 4055 4056 if (!mTransparentRegion.equals(mPreviousTransparentRegion)) { 4057 mPreviousTransparentRegion.set(mTransparentRegion); 4058 mFullRedrawNeeded = true; 4059 // TODO: Ideally we would do this in prepareSurfaces, 4060 // but prepareSurfaces is currently working under 4061 // the assumption that we paused the render thread 4062 // via the WM relayout code path. We probably eventually 4063 // want to synchronize transparent region hint changes 4064 // with draws. 4065 SurfaceControl sc = getSurfaceControl(); 4066 if (sc.isValid()) { 4067 mTransaction.setTransparentRegionHint(sc, mTransparentRegion).apply(); 4068 } 4069 } 4070 } 4071 4072 if (DBG) { 4073 System.out.println("======================================"); 4074 System.out.println("performTraversals -- after setFrame"); 4075 host.debug(); 4076 } 4077 } 4078 4079 boolean didUseTransaction = false; 4080 // These callbacks will trigger SurfaceView SurfaceHolder.Callbacks and must be invoked 4081 // after the measure pass. If its invoked before the measure pass and the app modifies 4082 // the view hierarchy in the callbacks, we could leave the views in a broken state. 4083 if (surfaceCreated) { 4084 notifySurfaceCreated(mTransaction); 4085 didUseTransaction = true; 4086 } else if (surfaceReplaced) { 4087 notifySurfaceReplaced(mTransaction); 4088 didUseTransaction = true; 4089 } else if (surfaceDestroyed) { 4090 notifySurfaceDestroyed(); 4091 } 4092 4093 if (didUseTransaction) { 4094 applyTransactionOnDraw(mTransaction); 4095 } 4096 4097 if (triggerGlobalLayoutListener) { 4098 mAttachInfo.mRecomputeGlobalAttributes = false; 4099 mAttachInfo.mTreeObserver.dispatchOnGlobalLayout(); 4100 } 4101 4102 Rect contentInsets = null; 4103 Rect visibleInsets = null; 4104 Region touchableRegion = null; 4105 int touchableInsetMode = TOUCHABLE_INSETS_REGION; 4106 boolean computedInternalInsets = false; 4107 if (computesInternalInsets) { 4108 final ViewTreeObserver.InternalInsetsInfo insets = mAttachInfo.mGivenInternalInsets; 4109 4110 // Clear the original insets. 4111 insets.reset(); 4112 4113 // Compute new insets in place. 4114 mAttachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets); 4115 mAttachInfo.mHasNonEmptyGivenInternalInsets = !insets.isEmpty(); 4116 4117 // Tell the window manager. 4118 if (insetsPending || !mLastGivenInsets.equals(insets)) { 4119 mLastGivenInsets.set(insets); 4120 4121 // Translate insets to screen coordinates if needed. 4122 if (mTranslator != null) { 4123 contentInsets = mTranslator.getTranslatedContentInsets(insets.contentInsets); 4124 visibleInsets = mTranslator.getTranslatedVisibleInsets(insets.visibleInsets); 4125 touchableRegion = mTranslator.getTranslatedTouchableArea(insets.touchableRegion); 4126 } else { 4127 contentInsets = insets.contentInsets; 4128 visibleInsets = insets.visibleInsets; 4129 touchableRegion = insets.touchableRegion; 4130 } 4131 computedInternalInsets = true; 4132 } 4133 touchableInsetMode = insets.mTouchableInsets; 4134 } 4135 boolean needsSetInsets = computedInternalInsets; 4136 needsSetInsets |= !Objects.equals(mPreviousTouchableRegion, mTouchableRegion) && 4137 (mTouchableRegion != null); 4138 if (needsSetInsets) { 4139 if (mTouchableRegion != null) { 4140 if (mPreviousTouchableRegion == null) { 4141 mPreviousTouchableRegion = new Region(); 4142 } 4143 mPreviousTouchableRegion.set(mTouchableRegion); 4144 if (touchableInsetMode != TOUCHABLE_INSETS_REGION) { 4145 Log.e(mTag, "Setting touchableInsetMode to non TOUCHABLE_INSETS_REGION" + 4146 " from OnComputeInternalInsets, while also using setTouchableRegion" + 4147 " causes setTouchableRegion to be ignored"); 4148 } 4149 } else { 4150 mPreviousTouchableRegion = null; 4151 } 4152 if (contentInsets == null) contentInsets = new Rect(0,0,0,0); 4153 if (visibleInsets == null) visibleInsets = new Rect(0,0,0,0); 4154 if (touchableRegion == null) { 4155 touchableRegion = mTouchableRegion; 4156 } else if (touchableRegion != null && mTouchableRegion != null) { 4157 touchableRegion.op(touchableRegion, mTouchableRegion, Region.Op.UNION); 4158 } 4159 try { 4160 mWindowSession.setInsets(mWindow, touchableInsetMode, 4161 contentInsets, visibleInsets, touchableRegion); 4162 } catch (RemoteException e) { 4163 throw e.rethrowFromSystemServer(); 4164 } 4165 } else if (mTouchableRegion == null && mPreviousTouchableRegion != null) { 4166 mPreviousTouchableRegion = null; 4167 try { 4168 mWindowSession.clearTouchableRegion(mWindow); 4169 } catch (RemoteException e) { 4170 throw e.rethrowFromSystemServer(); 4171 } 4172 } 4173 4174 if (mFirst) { 4175 if (sAlwaysAssignFocus || !isInTouchMode()) { 4176 // handle first focus request 4177 if (DEBUG_INPUT_RESIZE) { 4178 Log.v(mTag, "First: mView.hasFocus()=" + mView.hasFocus()); 4179 } 4180 if (mView != null) { 4181 if (!mView.hasFocus()) { 4182 mView.restoreDefaultFocus(); 4183 if (DEBUG_INPUT_RESIZE) { 4184 Log.v(mTag, "First: requested focused view=" + mView.findFocus()); 4185 } 4186 } else { 4187 if (DEBUG_INPUT_RESIZE) { 4188 Log.v(mTag, "First: existing focused view=" + mView.findFocus()); 4189 } 4190 } 4191 } 4192 } else { 4193 // Some views (like ScrollView) won't hand focus to descendants that aren't within 4194 // their viewport. Before layout, there's a good change these views are size 0 4195 // which means no children can get focus. After layout, this view now has size, but 4196 // is not guaranteed to hand-off focus to a focusable child (specifically, the edge- 4197 // case where the child has a size prior to layout and thus won't trigger 4198 // focusableViewAvailable). 4199 View focused = mView.findFocus(); 4200 if (focused instanceof ViewGroup 4201 && ((ViewGroup) focused).getDescendantFocusability() 4202 == ViewGroup.FOCUS_AFTER_DESCENDANTS) { 4203 focused.restoreDefaultFocus(); 4204 } 4205 } 4206 //#ifdef OPLUS_EXTENSION_HOOK 4207 //Honzhu@ANDROID.VIEW, 2020/07/20, add for Optimize app startup speed 4208 mViewRootImplExt.checkIsFragmentAnimUI(); 4209 //#endif /* OPLUS_EXTENSION_HOOK */ 4210 } 4211 4212 final boolean changedVisibility = (viewVisibilityChanged || mFirst) && isViewVisible; 4213 if (changedVisibility) { 4214 maybeFireAccessibilityWindowStateChangedEvent(); 4215 } 4216 4217 mFirst = false; 4218 mWillDrawSoon = false; 4219 mNewSurfaceNeeded = false; 4220 mViewVisibility = viewVisibility; 4221 4222 final boolean hasWindowFocus = mAttachInfo.mHasWindowFocus && isViewVisible; 4223 mImeFocusController.onTraversal(hasWindowFocus, mWindowAttributes); 4224 4225 if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { 4226 reportNextDraw("first_relayout"); 4227 } 4228 4229 mCheckIfCanDraw = isSyncRequest || cancelDraw; 4230 4231 boolean cancelDueToPreDrawListener = mAttachInfo.mTreeObserver.dispatchOnPreDraw(); 4232 boolean cancelAndRedraw = cancelDueToPreDrawListener 4233 || (cancelDraw && mDrewOnceForSync); 4234 //#ifdef OPLUS_EXTENSION_HOOK 4235 //Guofu.Yang@@ANDROID.WMS 2023/03/14,Add for fixed bug 5268134,5132324 4236 cancelAndRedraw = mViewRootImplExt.cancelAndRedraw(mTag,cancelAndRedraw,isViewVisible,mSyncBuffer); 4237 //#endif // OPLUS_EXTENSION_HOOK 4238 4239 if (!cancelAndRedraw) { 4240 // A sync was already requested before the WMS requested sync. This means we need to 4241 // sync the buffer, regardless if WMS wants to sync the buffer. 4242 if (mActiveSurfaceSyncGroup != null) { 4243 mSyncBuffer = true; 4244 } 4245 4246 createSyncIfNeeded(); 4247 notifyDrawStarted(isInWMSRequestedSync()); 4248 mDrewOnceForSync = true; 4249 4250 // If the active SSG is also requesting to sync a buffer, the following needs to happen 4251 // 1. Ensure we keep track of the number of active syncs to know when to disable RT 4252 // RT animations that conflict with syncing a buffer. 4253 // 2. Add a safeguard SSG to prevent multiple SSG that sync buffers from being submitted 4254 // out of order. 4255 if (mActiveSurfaceSyncGroup != null && mSyncBuffer) { 4256 updateSyncInProgressCount(mActiveSurfaceSyncGroup); 4257 safeguardOverlappingSyncs(mActiveSurfaceSyncGroup); 4258 } 4259 } 4260 // #ifdef OPLUS_FEATURE_EXTENSION_HOOKS 4261 // Bard.Zhang@Android.UIFramework 2023-10-30 Add for : debug 6429918 4262 else { 4263 Log.w(TAG, "cancelAndRedraw cancelDueToPreDrawListener " + cancelDueToPreDrawListener 4264 + " cancelDraw " + cancelDraw 4265 + " mDrewOnceForSync " + mDrewOnceForSync 4266 + " isSyncRequest " + isSyncRequest); 4267 } 4268 // #endif /* OPLUS_FEATURE_EXTENSION_HOOKS */ 4269 4270 if (!isViewVisible) { 4271 mLastPerformTraversalsSkipDrawReason = "view_not_visible"; 4272 if (mPendingTransitions != null && mPendingTransitions.size() > 0) { 4273 for (int i = 0; i < mPendingTransitions.size(); ++i) { 4274 mPendingTransitions.get(i).endChangingAnimations(); 4275 } 4276 mPendingTransitions.clear(); 4277 } 4278 4279 if (mActiveSurfaceSyncGroup != null) { 4280 mActiveSurfaceSyncGroup.markSyncReady(); 4281 } 4282 } else if (cancelAndRedraw) { 4283 mLastPerformTraversalsSkipDrawReason = cancelDueToPreDrawListener 4284 ? "predraw_" + mAttachInfo.mTreeObserver.getLastDispatchOnPreDrawCanceledReason() 4285 : "cancel_" + cancelReason; 4286 // Try again 4287 scheduleTraversals(); 4288 } else { 4289 if (mPendingTransitions != null && mPendingTransitions.size() > 0) { 4290 for (int i = 0; i < mPendingTransitions.size(); ++i) { 4291 mPendingTransitions.get(i).startChangingAnimations(); 4292 } 4293 mPendingTransitions.clear(); 4294 } 4295 if (!performDraw(mActiveSurfaceSyncGroup) && mActiveSurfaceSyncGroup != null) { 4296 mActiveSurfaceSyncGroup.markSyncReady(); 4297 } 4298 } 4299 4300 if (mAttachInfo.mContentCaptureEvents != null) { 4301 notifyContentCaptureEvents(); 4302 } 4303 mIsInTraversal = false; 4304 mRelayoutRequested = false; 4305 4306 if (!cancelAndRedraw) { 4307 mReportNextDraw = false; 4308 mLastReportNextDrawReason = null; 4309 mActiveSurfaceSyncGroup = null; 4310 mSyncBuffer = false; 4311 if (isInWMSRequestedSync()) { 4312 mWmsRequestSyncGroup.markSyncReady(); 4313 mWmsRequestSyncGroup = null; 4314 mWmsRequestSyncGroupState = WMS_SYNC_NONE; 4315 } 4316 } 4317 4318 // #ifdef OPLUS_FEATURE_VIEW_DEBUG 4319 // Bard.Zhang@Android.UIFramework 2023-01-28 Add for : view debug 4320 mViewRootImplExt.markOnPerformTraversalsEnd(host); 4321 // #endif /* OPLUS_FEATURE_VIEW_DEBUG */ 4322 4323 // #ifdef OPLUS_EXTENSION_HOOK 4324 // yanliang@Android.Performance 2023-02-13 Add for Optimize sliding effect 4325 mViewRootImplExt.checkPendingBufferCountSetting(mSurface); 4326 // #endif /*OPLUS_EXTENSION_HOOK*/ 4327 } 4328 解释里面的每行代码
最新发布
09-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冉冉同学_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值