Skip to content

Commit 4819c88

Browse files
committed
fix(android-old-arch): reset root views to fix View ID conflict
This would have an impact on old arch, Android, RN >= 0.77, notably with suspend/resume installMode
1 parent b0907b4 commit 4819c88

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

android/app/proguard-rules.pro

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# Invoked via reflection, when setting js bundle.
2020
-keepclassmembers class com.facebook.react.ReactInstanceManager {
2121
private final ** mBundleLoader;
22+
private ** mAttachedReactRoots;
2223
}
2324
-keepclassmembers class com.facebook.react.runtime.ReactHostImpl {
2425
private final ** mReactHostDelegate;
@@ -27,5 +28,13 @@
2728
-keep interface com.facebook.react.runtime.ReactHostDelegate { *; }
2829
-keep class * implements com.facebook.react.runtime.ReactHostDelegate { *; }
2930

31+
# Invoked via reflection, when resetting root views.
32+
-keepclassmembers interface com.facebook.react.ReactRoot {
33+
public ** getRootViewGroup();
34+
}
35+
-keepclassmembers class * implements com.facebook.react.ReactRoot {
36+
public ** getRootViewGroup();
37+
}
38+
3039
# Can't find referenced class org.bouncycastle.**
3140
-dontwarn com.nimbusds.jose.**

android/app/src/main/java/com/appzung/codepush/react/CodePushNativeModule.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.os.Looper;
88
import android.view.Choreographer;
99
import android.view.View;
10+
import android.view.ViewGroup;
1011

1112
import androidx.annotation.OptIn;
1213

@@ -268,6 +269,7 @@ private void loadBundle() {
268269
@Override
269270
public void run() {
270271
try {
272+
resetReactRootViews(instanceManager);
271273
instanceManager.recreateReactContextInBackground();
272274
mCodePush.initializeUpdateAfterRestart();
273275
} catch (Exception e) {
@@ -315,6 +317,26 @@ private void clearLifecycleEventListener() {
315317
}
316318
}
317319

320+
private void resetReactRootViews(ReactInstanceManager instanceManager) throws NoSuchFieldException, IllegalAccessException {
321+
Field mAttachedReactRootsField = instanceManager.getClass().getDeclaredField("mAttachedReactRoots");
322+
mAttachedReactRootsField.setAccessible(true);
323+
java.util.Set<?> mAttachedReactRoots = (java.util.Set<?>) mAttachedReactRootsField.get(instanceManager);
324+
if (mAttachedReactRoots != null) {
325+
for (Object reactRoot : mAttachedReactRoots) {
326+
try {
327+
Method getRootViewGroupMethod = reactRoot.getClass().getMethod("getRootViewGroup");
328+
ViewGroup rootViewGroup = (ViewGroup) getRootViewGroupMethod.invoke(reactRoot);
329+
if (rootViewGroup != null) {
330+
rootViewGroup.removeAllViews();
331+
rootViewGroup.setId(View.NO_ID);
332+
}
333+
} catch (Exception e) {
334+
CodePushUtils.log("Failed to reset root view: " + e.getMessage());
335+
}
336+
}
337+
}
338+
}
339+
318340
// Use reflection to find the ReactInstanceManager. See #556 for a proposal for a less brittle way to approach this.
319341
private ReactInstanceManager resolveInstanceManager() throws NoSuchFieldException, IllegalAccessException {
320342
ReactInstanceManager instanceManager = CodePush.getReactInstanceManager();

0 commit comments

Comments
 (0)