Browse Source

lifecycle of reactContext fix, refactored the tangled mess in the Application

Daniel Zlotin 8 years ago
parent
commit
58620a9b9c

+ 25
- 57
android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java View File

@@ -5,28 +5,31 @@ import android.os.Handler;
5 5
 import android.support.annotation.Nullable;
6 6
 
7 7
 import com.facebook.react.ReactPackage;
8
-import com.facebook.react.bridge.ReactContext;
9 8
 import com.facebook.react.bridge.WritableMap;
10
-import com.facebook.react.shell.MainReactPackage;
11
-import com.reactnativenavigation.bridge.NavigationReactPackage;
12
-import com.reactnativenavigation.react.NavigationReactInstance;
9
+import com.reactnativenavigation.react.NavigationReactGateway;
10
+import com.reactnativenavigation.react.ReactGateway;
13 11
 
14
-import java.util.ArrayList;
15 12
 import java.util.List;
16 13
 
17 14
 public abstract class NavigationApplication extends Application {
18 15
 
19 16
     public static NavigationApplication instance;
20
-    private NavigationReactInstance navigationReactInstance;
17
+
18
+    private ReactGateway reactGateway;
21 19
     private Handler handler;
22 20
 
23 21
     @Override
24 22
     public void onCreate() {
25 23
         super.onCreate();
26 24
         instance = this;
25
+        reactGateway = new NavigationReactGateway();
27 26
         handler = new Handler(getMainLooper());
28 27
     }
29 28
 
29
+    public void startReactContext() {
30
+        reactGateway.startReactContextOnceInBackgroundAndExecuteJS();
31
+    }
32
+
30 33
     public void runOnMainThread(Runnable runnable) {
31 34
         handler.post(runnable);
32 35
     }
@@ -35,32 +38,12 @@ public abstract class NavigationApplication extends Application {
35 38
         handler.postDelayed(runnable, delay);
36 39
     }
37 40
 
38
-    public NavigationReactInstance getNavigationReactInstance() {
39
-        return navigationReactInstance;
41
+    public ReactGateway getReactGateway() {
42
+        return reactGateway;
40 43
     }
41 44
 
42
-    public final List<ReactPackage> createReactPackages() {
43
-        List<ReactPackage> list = new ArrayList<>();
44
-        list.add(new MainReactPackage());
45
-        list.add(new NavigationReactPackage());
46
-        addAdditionalReactPackagesIfNeeded(list);
47
-        return list;
48
-    }
49
-
50
-    private void addAdditionalReactPackagesIfNeeded(List<ReactPackage> list) {
51
-        List<ReactPackage> additionalReactPackages = createAdditionalReactPackages();
52
-        if (additionalReactPackages == null) {
53
-            return;
54
-        }
55
-
56
-        for (ReactPackage reactPackage : additionalReactPackages) {
57
-            if (reactPackage instanceof MainReactPackage)
58
-                throw new RuntimeException("Do not create a new MainReactPackage. This is created for you.");
59
-            if (reactPackage instanceof NavigationReactPackage)
60
-                throw new RuntimeException("Do not create a new NavigationReactPackage. This is created for you.");
61
-        }
62
-
63
-        list.addAll(additionalReactPackages);
45
+    public boolean isReactContextInitialized() {
46
+        return reactGateway.isInitialized();
64 47
     }
65 48
 
66 49
     public String getJsEntryFileName() {
@@ -71,52 +54,37 @@ public abstract class NavigationApplication extends Application {
71 54
         return "index.android.bundle";
72 55
     }
73 56
 
74
-    public ReactContext getReactContext() {
75
-        if (navigationReactInstance == null) {
76
-            return null;
77
-        }
78
-        return navigationReactInstance.getReactInstanceManager().getCurrentReactContext();
79
-    }
57
+    public abstract boolean isDebug();
80 58
 
81
-    public boolean isReactInstanceManagerInitialized() {
82
-        return navigationReactInstance != null && navigationReactInstance.getReactInstanceManager() != null;
83
-    }
59
+    @Nullable
60
+    public abstract List<ReactPackage> createAdditionalReactPackages();
84 61
 
62
+    //TODO move all these navigator junk elsewhere
85 63
     public void sendNavigatorEvent(String eventId, String navigatorEventId) {
86
-        if (navigationReactInstance == null) {
64
+        if (!isReactContextInitialized()) {
87 65
             return;
88 66
         }
89
-        navigationReactInstance.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId);
67
+        reactGateway.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId);
90 68
     }
91 69
 
92 70
     public void sendNavigatorEvent(String eventId, String navigatorEventId, WritableMap data) {
93
-        if (navigationReactInstance == null) {
71
+        if (!isReactContextInitialized()) {
94 72
             return;
95 73
         }
96
-        navigationReactInstance.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId, data);
74
+        reactGateway.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId, data);
97 75
     }
98 76
 
99 77
     public void sendEvent(String eventId, String navigatorEventId) {
100
-        if (navigationReactInstance == null) {
78
+        if (!isReactContextInitialized()) {
101 79
             return;
102 80
         }
103
-        navigationReactInstance.getReactEventEmitter().sendEvent(eventId, navigatorEventId);
81
+        reactGateway.getReactEventEmitter().sendEvent(eventId, navigatorEventId);
104 82
     }
105 83
 
106 84
     public void sendNavigatorEvent(String eventId, WritableMap arguments) {
107
-        if (navigationReactInstance == null) {
85
+        if (!isReactContextInitialized()) {
108 86
             return;
109 87
         }
110
-        navigationReactInstance.getReactEventEmitter().sendEvent(eventId, arguments);
111
-    }
112
-
113
-    public void startReactContext() {
114
-        navigationReactInstance = new NavigationReactInstance();
115
-        navigationReactInstance.startReactContextOnceInBackgroundAndExecuteJS();
88
+        reactGateway.getReactEventEmitter().sendEvent(eventId, arguments);
116 89
     }
117
-
118
-    public abstract boolean isDebug();
119
-
120
-    @Nullable
121
-    public abstract List<ReactPackage> createAdditionalReactPackages();
122 90
 }

+ 45
- 30
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java View File

@@ -15,12 +15,12 @@ import com.reactnativenavigation.params.ScreenParams;
15 15
 import com.reactnativenavigation.params.TitleBarButtonParams;
16 16
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
17 17
 import com.reactnativenavigation.react.JsDevReloadHandler;
18
-import com.reactnativenavigation.react.NavigationReactInstance;
18
+import com.reactnativenavigation.react.ReactGateway;
19 19
 import com.reactnativenavigation.react.RedboxPermission;
20 20
 
21 21
 import java.util.List;
22 22
 
23
-public class NavigationActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler, NavigationReactInstance.OnJsDevReloadListener {
23
+public class NavigationActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler, ReactGateway.OnJsDevReloadListener {
24 24
 
25 25
     /**
26 26
      * Although we start multiple activities, we make sure to pass Intent.CLEAR_TASK | Intent.NEW_TASK
@@ -39,9 +39,16 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
39 39
     @Override
40 40
     protected void onCreate(Bundle savedInstanceState) {
41 41
         super.onCreate(savedInstanceState);
42
+
43
+        if (!NavigationApplication.instance.isReactContextInitialized()) {
44
+            NavigationApplication.instance.startReactContext();
45
+            finish();
46
+            return;
47
+        }
48
+
42 49
         RedboxPermission.permissionToShowRedboxIfNeeded(this);
43 50
 
44
-        activityParams = NavigationCommandsHandler.getActivityParams(getIntent());
51
+        activityParams = NavigationCommandsHandler.parseActivityParams(getIntent());
45 52
 
46 53
         createLayout();
47 54
         createModalController();
@@ -59,29 +66,40 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
59 66
     @Override
60 67
     protected void onResume() {
61 68
         super.onResume();
69
+        if (isFinishing()) {
70
+            return;
71
+        }
72
+
62 73
         currentActivity = this;
63
-        getNavigationReactInstance().onResume(this, this, this);
74
+        NavigationApplication.instance.getReactGateway().onResume(this, this, this);
64 75
     }
65 76
 
66 77
     @Override
67 78
     protected void onPause() {
68 79
         super.onPause();
69 80
         currentActivity = null;
70
-        getNavigationReactInstance().onPause();
81
+        NavigationApplication.instance.getReactGateway().onPause();
71 82
     }
72 83
 
73 84
     @Override
74 85
     protected void onDestroy() {
75
-        modalController.destroy();
76
-        layout.destroy();
77
-        super.onDestroy();
86
+        if (modalController != null) {
87
+            modalController.destroy();
88
+        }
89
+        if (layout != null) {
90
+            layout.destroy();
91
+        }
78 92
         if (currentActivity == null || currentActivity.isFinishing()) {
79
-            getNavigationReactInstance().onHostDestroy();
93
+            if (NavigationApplication.instance.isReactContextInitialized()) {
94
+                NavigationApplication.instance.getReactGateway().onDestroyApp();
95
+            }
80 96
         }
97
+        super.onDestroy();
81 98
     }
82 99
 
83 100
     @Override
84 101
     public void onJsDevReload() {
102
+        modalController.destroy();
85 103
         layout.destroy();
86 104
     }
87 105
 
@@ -93,13 +111,13 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
93 111
     @Override
94 112
     public void onBackPressed() {
95 113
         if (!layout.onBackPressed()) {
96
-            getNavigationReactInstance().onBackPressed();
114
+            NavigationApplication.instance.getReactGateway().onBackPressed();
97 115
         }
98 116
     }
99 117
 
100 118
     @Override
101 119
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
102
-        getNavigationReactInstance().onActivityResult(requestCode, resultCode, data);
120
+        NavigationApplication.instance.getReactGateway().onActivityResult(requestCode, resultCode, data);
103 121
     }
104 122
 
105 123
     @Override
@@ -107,10 +125,6 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
107 125
         return JsDevReloadHandler.onKeyUp(getCurrentFocus(), keyCode) || super.onKeyUp(keyCode, event);
108 126
     }
109 127
 
110
-    private NavigationReactInstance getNavigationReactInstance() {
111
-        return NavigationApplication.instance.getNavigationReactInstance();
112
-    }
113
-
114 128
     void push(ScreenParams params) {
115 129
         if (modalController.isShowing()) {
116 130
             modalController.push(params);
@@ -143,12 +157,25 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
143 157
         }
144 158
     }
145 159
 
160
+    void showModal(ScreenParams screenParams) {
161
+        modalController.showModal(screenParams);
162
+    }
163
+
164
+    void dismissTopModal() {
165
+        modalController.dismissTopModal();
166
+    }
167
+
168
+    void dismissAllModals() {
169
+        modalController.dismissAllModals();
170
+    }
171
+
172
+    //TODO all these setters should be combined to something like setStyle
146 173
     void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
147 174
         layout.setTopBarVisible(screenInstanceId, hidden, animated);
148 175
         modalController.setTopBarVisible(screenInstanceId, hidden, animated);
149 176
     }
150 177
 
151
-    public void setBottomTabsVisible(boolean hidden, boolean animated) {
178
+    void setBottomTabsVisible(boolean hidden, boolean animated) {
152 179
         if (layout instanceof BottomTabsLayout) {
153 180
             ((BottomTabsLayout) layout).setBottomTabsVisible(hidden, animated);
154 181
         }
@@ -159,25 +186,13 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
159 186
         modalController.setTitleBarTitle(screenInstanceId, title);
160 187
     }
161 188
 
162
-    public void setTitleBarButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
189
+    void setTitleBarButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
163 190
         layout.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
164 191
         modalController.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
165 192
     }
166 193
 
167
-    public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButton) {
194
+    void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButton) {
168 195
         layout.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
169 196
         modalController.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
170 197
     }
171
-
172
-    void showModal(ScreenParams screenParams) {
173
-        modalController.showModal(screenParams);
174
-    }
175
-
176
-    void dismissTopModal() {
177
-        modalController.dismissTopModal();
178
-    }
179
-
180
-    void dismissAllModals() {
181
-        modalController.dismissAllModals();
182
-    }
183 198
 }

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationCommandsHandler.java View File

@@ -17,7 +17,7 @@ public class NavigationCommandsHandler {
17 17
 
18 18
     private static final String ACTIVITY_PARAMS_BUNDLE = "ACTIVITY_PARAMS_BUNDLE";
19 19
 
20
-    static ActivityParams getActivityParams(Intent intent) {
20
+    static ActivityParams parseActivityParams(Intent intent) {
21 21
         return ActivityParamsParser.parse(intent.getBundleExtra(NavigationCommandsHandler.ACTIVITY_PARAMS_BUNDLE));
22 22
     }
23 23
 

+ 10
- 29
android/app/src/main/java/com/reactnativenavigation/layouts/LayoutFactory.java View File

@@ -20,35 +20,16 @@ public class LayoutFactory {
20 20
     }
21 21
 
22 22
     private static Layout createBottomTabsScreenLayout(AppCompatActivity activity, ActivityParams params) {
23
+        if (params.tabParams.size() > 5) {
24
+            removeAllButTheFirst5Tabs(params);
25
+        }
23 26
         return new BottomTabsLayout(activity, params);
24 27
     }
25
-//
26
-//    private static void addContentWithMenuIfNeeded(Activity activity, Params params, LinearLayout root, FrameLayout content) {
27
-//        if (params.sideMenu.enabled) {
28
-//            DrawerLayout sideMenu = createSideMenu(activity, content);
29
-//            root.addView(sideMenu, new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1));
30
-//        } else {
31
-//            root.addView(content, new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1));
32
-//        }
33
-//    }
34
-//
35
-//    private static LinearLayout createRoot(Activity activity) {
36
-//        LinearLayout root = new LinearLayout(activity);
37
-//        root.setOrientation(LinearLayout.VERTICAL);
38
-//        return root;
39
-//    }
40
-//
41
-//    private static DrawerLayout createSideMenu(Activity activity, FrameLayout content) {
42
-//        DrawerLayout drawerLayout = new DrawerLayout(activity);
43
-//        FrameLayout drawerContent = new FrameLayout(activity);
44
-//        drawerLayout.addView(content, new DrawerLayout.LayoutParams(MATCH_PARENT, 0, 1));
45
-//        DrawerLayout.LayoutParams drawerContentParams = new DrawerLayout.LayoutParams(WRAP_CONTENT, MATCH_PARENT);
46
-//        drawerContentParams.gravity = Gravity.START;
47
-//        drawerLayout.addView(drawerContent, drawerContentParams);
48
-//        return drawerLayout;
49
-//    }
50
-//
51
-//    private static FrameLayout createContent(Activity activity) {
52
-//        return new FrameLayout(activity);
53
-//    }
28
+
29
+    private static void removeAllButTheFirst5Tabs(ActivityParams params) {
30
+        android.util.Log.e("LOG", "LayoutFactory:createBottomTabsScreenLayout() does not support more than 5 tabs, currently");
31
+        while (params.tabParams.size() > 5) {
32
+            params.tabParams.remove(params.tabParams.size() - 1);
33
+        }
34
+    }
54 35
 }

+ 2
- 3
android/app/src/main/java/com/reactnativenavigation/react/JsDevReloadHandler.java View File

@@ -13,10 +13,9 @@ public class JsDevReloadHandler {
13 13
 
14 14
     //TODO yuck.
15 15
     public static boolean onKeyUp(View currentFocus, int keyCode) {
16
-
17 16
         ReactInstanceManager reactInstanceManager = NavigationApplication
18 17
                 .instance
19
-                .getNavigationReactInstance()
18
+                .getReactGateway()
20 19
                 .getReactInstanceManager();
21 20
 
22 21
         if (reactInstanceManager != null &&
@@ -40,7 +39,7 @@ public class JsDevReloadHandler {
40 39
                                     shouldRefreshOnRR = false;
41 40
                                 }
42 41
                             },
43
-                            200);
42
+                            500);
44 43
                 }
45 44
             }
46 45
         }

android/app/src/main/java/com/reactnativenavigation/react/NavigationReactInstance.java → android/app/src/main/java/com/reactnativenavigation/react/NavigationReactGateway.java View File

@@ -1,69 +1,84 @@
1 1
 package com.reactnativenavigation.react;
2 2
 
3
+import android.app.Activity;
3 4
 import android.content.Intent;
4 5
 
5 6
 import com.facebook.react.LifecycleState;
6 7
 import com.facebook.react.ReactInstanceManager;
7 8
 import com.facebook.react.ReactPackage;
9
+import com.facebook.react.bridge.ReactContext;
8 10
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
11
+import com.facebook.react.shell.MainReactPackage;
9 12
 import com.reactnativenavigation.NavigationApplication;
10 13
 import com.reactnativenavigation.bridge.NavigationReactEventEmitter;
11
-import com.reactnativenavigation.controllers.NavigationActivity;
14
+import com.reactnativenavigation.bridge.NavigationReactPackage;
12 15
 
13
-public class NavigationReactInstance {
14
-    private final ReactInstanceManager reactInstanceManager;
15
-    private NavigationReactEventEmitter reactEventEmitter;
16
-    private OnJsDevReloadListener onJsDevReloadListener;
16
+import java.util.ArrayList;
17
+import java.util.List;
17 18
 
18
-    public interface OnJsDevReloadListener {
19
-        void onJsDevReload();
20
-    }
19
+public class NavigationReactGateway implements ReactGateway {
21 20
 
22
-    public NavigationReactInstance() {
23
-        reactInstanceManager = createReactInstanceManager();
24
-
25
-        if (NavigationApplication.instance.isDebug()) {
26
-            replaceJsDevReloadListener();
27
-        }
28
-    }
21
+    private OnJsDevReloadListener onJsDevReloadListener;
22
+    private ReactInstanceManager reactInstanceManager;
23
+    private NavigationReactEventEmitter reactEventEmitter;
29 24
 
30
-    public ReactInstanceManager getReactInstanceManager() {
31
-        return reactInstanceManager;
25
+    public NavigationReactGateway() {
26
+        reactInstanceManager = createReactInstanceManager();
32 27
     }
33 28
 
34 29
     public void startReactContextOnceInBackgroundAndExecuteJS() {
30
+        if (reactInstanceManager == null) {
31
+            reactInstanceManager = createReactInstanceManager();
32
+        }
35 33
         if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
36 34
             reactInstanceManager.createReactContextInBackground();
37 35
         }
38 36
     }
39 37
 
40
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
41
-        reactInstanceManager.onActivityResult(requestCode, resultCode, data);
38
+    public boolean isInitialized() {
39
+        return reactInstanceManager != null && reactInstanceManager.getCurrentReactContext() != null;
40
+    }
41
+
42
+    public ReactContext getReactContext() {
43
+        return reactInstanceManager.getCurrentReactContext();
44
+    }
45
+
46
+    public NavigationReactEventEmitter getReactEventEmitter() {
47
+        return reactEventEmitter;
48
+    }
49
+
50
+    public ReactInstanceManager getReactInstanceManager() {
51
+        return reactInstanceManager;
42 52
     }
43 53
 
44 54
     public void onBackPressed() {
45 55
         reactInstanceManager.onBackPressed();
46 56
     }
47 57
 
48
-    public void onResume(NavigationActivity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener) {
49
-        this.onJsDevReloadListener = onJsDevReloadListener;
50
-        reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
51
-        reactEventEmitter = new NavigationReactEventEmitter(reactInstanceManager.getCurrentReactContext());
58
+    public void onDestroyApp() {
59
+        reactInstanceManager.onHostDestroy();
60
+        reactInstanceManager.destroy();
61
+        reactInstanceManager = null;
52 62
     }
53 63
 
54 64
     public void onPause() {
65
+        reactInstanceManager.onHostPause();
55 66
         onJsDevReloadListener = null;
56 67
         reactEventEmitter = null;
57
-        reactInstanceManager.onHostPause();
58 68
     }
59 69
 
60
-    public void onHostDestroy() {
61
-        reactInstanceManager.onHostDestroy();
62
-        reactInstanceManager.destroy();
70
+    public void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener) {
71
+        this.onJsDevReloadListener = onJsDevReloadListener;
72
+        reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
73
+        reactEventEmitter = new NavigationReactEventEmitter(reactInstanceManager.getCurrentReactContext());
63 74
     }
64 75
 
65
-    private void replaceJsDevReloadListener() {
66
-        new JsDevReloadListenerReplacer(reactInstanceManager, new JsDevReloadListenerReplacer.Listener() {
76
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
77
+        reactInstanceManager.onActivityResult(requestCode, resultCode, data);
78
+    }
79
+
80
+    private void replaceJsDevReloadListener(ReactInstanceManager manager) {
81
+        new JsDevReloadListenerReplacer(manager, new JsDevReloadListenerReplacer.Listener() {
67 82
             @Override
68 83
             public void onJsDevReload() {
69 84
                 if (onJsDevReloadListener != null)
@@ -80,14 +95,40 @@ public class NavigationReactInstance {
80 95
                 .setUseDeveloperSupport(NavigationApplication.instance.isDebug())
81 96
                 .setInitialLifecycleState(LifecycleState.BEFORE_RESUME);
82 97
 
83
-        for (ReactPackage reactPackage : NavigationApplication.instance.createReactPackages()) {
98
+        for (ReactPackage reactPackage : createReactPackages()) {
84 99
             builder.addPackage(reactPackage);
85 100
         }
86 101
 
87
-        return builder.build();
102
+        ReactInstanceManager manager = builder.build();
103
+
104
+        if (NavigationApplication.instance.isDebug()) {
105
+            replaceJsDevReloadListener(manager);
106
+        }
107
+
108
+        return manager;
88 109
     }
89 110
 
90
-    public NavigationReactEventEmitter getReactEventEmitter() {
91
-        return reactEventEmitter;
111
+    private List<ReactPackage> createReactPackages() {
112
+        List<ReactPackage> list = new ArrayList<>();
113
+        list.add(new MainReactPackage());
114
+        list.add(new NavigationReactPackage());
115
+        addAdditionalReactPackagesIfNeeded(list);
116
+        return list;
117
+    }
118
+
119
+    private void addAdditionalReactPackagesIfNeeded(List<ReactPackage> list) {
120
+        List<ReactPackage> additionalReactPackages = NavigationApplication.instance.createAdditionalReactPackages();
121
+        if (additionalReactPackages == null) {
122
+            return;
123
+        }
124
+
125
+        for (ReactPackage reactPackage : additionalReactPackages) {
126
+            if (reactPackage instanceof MainReactPackage)
127
+                throw new RuntimeException("Do not create a new MainReactPackage. This is created for you.");
128
+            if (reactPackage instanceof NavigationReactPackage)
129
+                throw new RuntimeException("Do not create a new NavigationReactPackage. This is created for you.");
130
+        }
131
+
132
+        list.addAll(additionalReactPackages);
92 133
     }
93 134
 }

+ 36
- 0
android/app/src/main/java/com/reactnativenavigation/react/ReactGateway.java View File

@@ -0,0 +1,36 @@
1
+package com.reactnativenavigation.react;
2
+
3
+import android.app.Activity;
4
+import android.content.Intent;
5
+
6
+import com.facebook.react.ReactInstanceManager;
7
+import com.facebook.react.bridge.ReactContext;
8
+import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
9
+import com.reactnativenavigation.bridge.NavigationReactEventEmitter;
10
+
11
+public interface ReactGateway {
12
+
13
+    interface OnJsDevReloadListener {
14
+        void onJsDevReload();
15
+    }
16
+
17
+    void startReactContextOnceInBackgroundAndExecuteJS();
18
+
19
+    boolean isInitialized();
20
+
21
+    ReactContext getReactContext();
22
+
23
+    NavigationReactEventEmitter getReactEventEmitter();
24
+
25
+    ReactInstanceManager getReactInstanceManager();
26
+
27
+    void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener);
28
+
29
+    void onPause();
30
+
31
+    void onDestroyApp();
32
+
33
+    void onBackPressed();
34
+
35
+    void onActivityResult(int requestCode, int resultCode, Intent data);
36
+}

+ 1
- 3
android/app/src/main/java/com/reactnativenavigation/views/ContentView.java View File

@@ -3,7 +3,6 @@ package com.reactnativenavigation.views;
3 3
 import android.content.Context;
4 4
 import android.os.Bundle;
5 5
 
6
-import com.facebook.react.ReactInstanceManager;
7 6
 import com.facebook.react.ReactRootView;
8 7
 import com.reactnativenavigation.NavigationApplication;
9 8
 import com.reactnativenavigation.params.ScreenParams;
@@ -40,8 +39,7 @@ public class ContentView extends ReactRootView {
40 39
     }
41 40
 
42 41
     private void attachToJS() {
43
-        ReactInstanceManager react = NavigationApplication.instance.getNavigationReactInstance().getReactInstanceManager();
44
-        startReactApplication(react, screenId, passProps);
42
+        startReactApplication(NavigationApplication.instance.getReactGateway().getReactInstanceManager(), screenId, passProps);
45 43
     }
46 44
 
47 45
     private Bundle mergePropsAndNavigationParams(ScreenParams screenParams, Bundle passProps) {