From 763b06b6b5c77e3352e4de931357dc8fad3fb4d7 Mon Sep 17 00:00:00 2001 From: floydkim Date: Thu, 6 Nov 2025 23:12:25 +0900 Subject: [PATCH 1/3] fix(Android): support React Native version 0.81+ by updating field access for ReactHost --- android/app/proguard-rules.pro | 6 +++-- .../codepush/react/CodePushNativeModule.java | 23 +++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 9eb36cb2e..239a4a553 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -21,7 +21,8 @@ private final ** mBundleLoader; } -keepclassmembers class com.facebook.react.ReactDelegate { - private ** mReactHost; # bridgeless + private ** mReactHost; # RN < 0.81 + private ** reactHost; # RN 0.81+ public void reload(...); # RN 0.74 and above } # bridgeless @@ -30,7 +31,8 @@ } # bridgeless -keepclassmembers class com.facebook.react.runtime.ReactHostImpl { - private final ** mReactHostDelegate; + private final ** mReactHostDelegate; # RN < 0.81 + private final ** reactHostDelegate; # RN 0.81+ } # Can't find referenced class org.bouncycastle.** diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java index 1aaee51ee..cfcb18062 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java @@ -12,7 +12,6 @@ import com.facebook.react.ReactDelegate; import com.facebook.react.ReactHost; -import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactActivity; import com.facebook.react.ReactRootView; import com.facebook.react.bridge.Arguments; @@ -140,9 +139,16 @@ private void setJSBundle(String latestJSBundleFile) throws IllegalAccessExceptio @OptIn(markerClass = UnstableReactNativeAPI.class) private void setJSBundleLoaderBridgeless(ReactHost reactHost, JSBundleLoader latestJSBundleLoader) throws NoSuchFieldException, IllegalAccessException { - Field mReactHostDelegateField = reactHost.getClass().getDeclaredField("mReactHostDelegate"); - mReactHostDelegateField.setAccessible(true); - ReactHostDelegate reactHostDelegate = (ReactHostDelegate) mReactHostDelegateField.get(reactHost); + Field reactHostDelegateField; + try { + // RN < 0.81 + reactHostDelegateField = reactHost.getClass().getDeclaredField("mReactHostDelegate"); + } catch (NoSuchFieldException e) { + // RN >= 0.81 + reactHostDelegateField = reactHost.getClass().getDeclaredField("reactHostDelegate"); + } + reactHostDelegateField.setAccessible(true); + ReactHostDelegate reactHostDelegate = (ReactHostDelegate) reactHostDelegateField.get(reactHost); assert reactHostDelegate != null; Field jsBundleLoaderField = reactHostDelegate.getClass().getDeclaredField("jsBundleLoader"); jsBundleLoaderField.setAccessible(true); @@ -220,7 +226,14 @@ private ReactHost resolveReactHost() { } try { - Field reactHostField = reactDelegate.getClass().getDeclaredField("mReactHost"); + Field reactHostField; + try { + // RN < 0.81 + reactHostField = reactDelegate.getClass().getDeclaredField("mReactHost"); + } catch (NoSuchFieldException e) { + // RN >= 0.81 + reactHostField = reactDelegate.getClass().getDeclaredField("reactHost"); + } reactHostField.setAccessible(true); return (ReactHost) reactHostField.get(reactDelegate); } catch (Exception e) { From 0ee06084443800deec228c82948a6824323e2ed5 Mon Sep 17 00:00:00 2001 From: Floyd Kim Date: Fri, 7 Nov 2025 15:42:07 +0900 Subject: [PATCH 2/3] fix(Android): update not working properly --- android/app/proguard-rules.pro | 5 ---- .../codepush/react/CodePushNativeModule.java | 28 +++++++++---------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 239a4a553..a86b4ff4c 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -20,11 +20,6 @@ -keepclassmembers class com.facebook.react.ReactInstanceManager { private final ** mBundleLoader; } --keepclassmembers class com.facebook.react.ReactDelegate { - private ** mReactHost; # RN < 0.81 - private ** reactHost; # RN 0.81+ - public void reload(...); # RN 0.74 and above -} # bridgeless -keepclassmembers class com.facebook.react.defaults.DefaultReactHostDelegate { private ** jsBundleLoader; diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java index cfcb18062..392301caf 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java @@ -13,6 +13,7 @@ import com.facebook.react.ReactDelegate; import com.facebook.react.ReactHost; import com.facebook.react.ReactActivity; +import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactRootView; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.JSBundleLoader; @@ -125,7 +126,9 @@ private void setJSBundle(String latestJSBundleFile) throws IllegalAccessExceptio ReactHost reactHost = resolveReactHost(); if (reactHost == null) { + CodePushUtils.log("Unable to resolve ReactHost"); // Bridge, Old Architecture + setJSBundleLoaderBridge(latestJSBundleLoader); return; } @@ -137,6 +140,15 @@ private void setJSBundle(String latestJSBundleFile) throws IllegalAccessExceptio } } + private void setJSBundleLoaderBridge(JSBundleLoader latestJSBundleLoader) throws NoSuchFieldException, IllegalAccessException { + ReactDelegate reactDelegate = resolveReactDelegate(); + assert reactDelegate != null; + ReactInstanceManager instanceManager = reactDelegate.getReactInstanceManager(); + Field bundleLoaderField = instanceManager.getClass().getDeclaredField("mBundleLoader"); + bundleLoaderField.setAccessible(true); + bundleLoaderField.set(instanceManager, latestJSBundleLoader); + } + @OptIn(markerClass = UnstableReactNativeAPI.class) private void setJSBundleLoaderBridgeless(ReactHost reactHost, JSBundleLoader latestJSBundleLoader) throws NoSuchFieldException, IllegalAccessException { Field reactHostDelegateField; @@ -222,23 +234,11 @@ private ReactDelegate resolveReactDelegate() { private ReactHost resolveReactHost() { ReactDelegate reactDelegate = resolveReactDelegate(); if (reactDelegate == null) { + CodePushUtils.log("Unable to resolve ReactDelegate"); return null; } - try { - Field reactHostField; - try { - // RN < 0.81 - reactHostField = reactDelegate.getClass().getDeclaredField("mReactHost"); - } catch (NoSuchFieldException e) { - // RN >= 0.81 - reactHostField = reactDelegate.getClass().getDeclaredField("reactHost"); - } - reactHostField.setAccessible(true); - return (ReactHost) reactHostField.get(reactDelegate); - } catch (Exception e) { - return null; - } + return reactDelegate.getReactHost(); } private void restartAppInternal(boolean onlyIfUpdateIsPending) { From 613223692141e32fc417112c8919e6822be2b40e Mon Sep 17 00:00:00 2001 From: Floyd Kim Date: Fri, 7 Nov 2025 15:59:25 +0900 Subject: [PATCH 3/3] docs: add note for users on React Native 0.76 or lower --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7b1314eb7..340150a5d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ Supports React Native 0.74 ~ 0.82. +> [!NOTE] +> If you are using React Native 0.76 or lower, please use version `12.0.2` of this library. + (Tested on the React Native CLI template apps) ### ✅ Requirements