55import android .os .Handler ;
66import android .os .Looper ;
77import android .provider .Settings ;
8+ import android .view .View ;
89
910import com .facebook .react .ReactApplication ;
1011import com .facebook .react .ReactInstanceManager ;
12+ import com .facebook .react .ReactRootView ;
1113import com .facebook .react .bridge .Arguments ;
1214import com .facebook .react .bridge .LifecycleEventListener ;
1315import com .facebook .react .bridge .Promise ;
2931import java .lang .reflect .Method ;
3032import java .util .Date ;
3133import java .util .HashMap ;
34+ import java .util .List ;
3235import java .util .Map ;
3336
3437public class CodePushNativeModule extends ReactContextBaseJavaModule {
@@ -101,7 +104,7 @@ private void setJSBundle(ReactInstanceManager instanceManager, String latestJSBu
101104 Class <?> jsBundleLoaderClass = Class .forName ("com.facebook.react.cxxbridge.JSBundleLoader" );
102105 Method createFileLoaderMethod = null ;
103106 String createFileLoaderMethodName = latestJSBundleFile .toLowerCase ().startsWith ("assets://" )
104- ? "createAssetLoader" : "createFileLoader" ;
107+ ? "createAssetLoader" : "createFileLoader" ;
105108
106109 Method [] methods = jsBundleLoaderClass .getDeclaredMethods ();
107110 for (Method method : methods ) {
@@ -157,6 +160,11 @@ private void loadBundle() {
157160 @ Override
158161 public void run () {
159162 try {
163+ // This workaround has been implemented in order to fix https://github.com/facebook/react-native/issues/14533
164+ // resetReactRootViews allows to call recreateReactContextInBackground without any exceptions
165+ // This fix also relates to https://github.com/Microsoft/react-native-code-push/issues/878
166+ resetReactRootViews (instanceManager );
167+
160168 instanceManager .recreateReactContextInBackground ();
161169 mCodePush .initializeUpdateAfterRestart ();
162170 } catch (Exception e ) {
@@ -174,6 +182,17 @@ public void run() {
174182 }
175183 }
176184
185+ private void resetReactRootViews (ReactInstanceManager instanceManager ) throws NoSuchFieldException , IllegalAccessException {
186+ Field mAttachedRootViewsField = instanceManager .getClass ().getDeclaredField ("mAttachedRootViews" );
187+ mAttachedRootViewsField .setAccessible (true );
188+ List <ReactRootView > mAttachedRootViews = (List <ReactRootView >)mAttachedRootViewsField .get (instanceManager );
189+ for (ReactRootView reactRootView : mAttachedRootViews ) {
190+ reactRootView .removeAllViews ();
191+ reactRootView .setId (View .NO_ID );
192+ }
193+ mAttachedRootViewsField .set (instanceManager , mAttachedRootViews );
194+ }
195+
177196 private void clearLifecycleEventListener () {
178197 // Remove LifecycleEventListener to prevent infinite restart loop
179198 if (mLifecycleEventListener != null ) {
0 commit comments