瀏覽代碼

fix: Cannot add a null child view to a ViewGroup

https://console.firebase.google.com/project/yoki-b5692/crashlytics/app/android:com.partyjoy.yoki/issues/a0a40356aa1f7f55378f92fe25219da3?hl=zh-cn&time=7d&types=crash&sessionEventKey=68DFF34A009C00013A17702AC35C528D_2135475227445748731
XiaodongLin 6 月之前
父節點
當前提交
0332b89072

+ 11 - 0
app/src/main/java/com/adealink/weparty/commonui/ext/ViewExt.kt

@@ -240,4 +240,15 @@ fun View.setOnTouchDelegate(expandedTouchWidth: Int) {
 
 fun Activity.contentView(): View? {
     return this.findViewById<View>(android.R.id.content)
+}
+
+
+/**
+ * 安全添加子 View 到 ViewGroup
+ * 如果 view 为 null 或已经有父 View,则不会添加
+ */
+fun ViewGroup.addViewSafe(view: View?) {
+    if (view == null) return          // 空对象直接返回
+    if (view.parent != null) return   // 已经有父 View,避免 IllegalStateException
+    this.addView(view)
 }

+ 4 - 1
module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoCallerComp.kt

@@ -7,6 +7,7 @@ import androidx.lifecycle.LifecycleOwner
 import com.adealink.weparty.call.constant.TAG_CALL_MATCH_MODE
 import com.adealink.weparty.call.match.matchManager
 import com.adealink.weparty.call.widget.BaseCallViewComponent
+import com.adealink.weparty.commonui.ext.addViewSafe
 import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.tencent.qcloud.tuikit.tuicallkit.view.component.videolayout.VideoView
@@ -49,7 +50,9 @@ class VideoCallerComp(
             (videoViewBig?.parent as ViewGroup).removeView(videoViewBig)
             bigVideoContainer.removeAllViews()
         }
-        bigVideoContainer.addView(videoViewBig)
+        if (videoViewBig != null) {
+            bigVideoContainer.addViewSafe(videoViewBig)
+        }
         if(matchManager.isMatchIdValid() && TUICallState.instance.callUserData.get().matchId == matchManager.getMatchId()) {
             Log.d(TAG_CALL_MATCH_MODE, "initBigRenderView, no need open in match mode begin")
             return

+ 7 - 6
module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoRoomComp.kt

@@ -22,6 +22,7 @@ import com.adealink.weparty.call.constant.TAG_CALL
 import com.adealink.weparty.call.constant.TAG_CALL_MATCH_MODE
 import com.adealink.weparty.call.match.matchManager
 import com.adealink.weparty.call.widget.BaseCallViewComponent
+import com.adealink.weparty.commonui.ext.addViewSafe
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine
@@ -162,13 +163,13 @@ class VideoRoomComp(
             if (TUICallState.instance.showLargeViewUserId.get() == bigVideoUser?.id) {
                 TUICallState.instance.showLargeViewUserId.set(smallVideoUser?.id)
 
-                smallVideoContainer?.addView(bigVideoView)
-                bigVideoContainer?.addView(smallVideoView)
+                smallVideoContainer?.addViewSafe(bigVideoView)
+                bigVideoContainer?.addViewSafe(smallVideoView)
             } else {
                 TUICallState.instance.showLargeViewUserId.set(bigVideoUser?.id)
 
-                smallVideoContainer?.addView(smallVideoView)
-                bigVideoContainer?.addView(bigVideoView)
+                smallVideoContainer?.addViewSafe(smallVideoView)
+                bigVideoContainer?.addViewSafe(bigVideoView)
             }
         }
     }
@@ -185,7 +186,7 @@ class VideoRoomComp(
                 smallVideoContainer.removeAllViews()
             }
             setSmallRenderViewOrientation()
-            smallVideoContainer.addView(smallVideoView)
+            smallVideoContainer.addViewSafe(smallVideoView)
             openVideo(smallVideoUser, smallVideoView, forceOpen)
         }
     }
@@ -200,7 +201,7 @@ class VideoRoomComp(
             (bigVideoView?.parent as ViewGroup).removeView(bigVideoView)
             bigVideoContainer.removeAllViews()
         }
-        bigVideoContainer.addView(bigVideoView)
+        bigVideoContainer.addViewSafe(bigVideoView)
         openVideo(bigVideoUser, bigVideoView, forceOpen)
     }