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
 import android.support.annotation.Nullable;
5
 import android.support.annotation.Nullable;
6
 
6
 
7
 import com.facebook.react.ReactPackage;
7
 import com.facebook.react.ReactPackage;
8
-import com.facebook.react.bridge.ReactContext;
9
 import com.facebook.react.bridge.WritableMap;
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
 import java.util.List;
12
 import java.util.List;
16
 
13
 
17
 public abstract class NavigationApplication extends Application {
14
 public abstract class NavigationApplication extends Application {
18
 
15
 
19
     public static NavigationApplication instance;
16
     public static NavigationApplication instance;
20
-    private NavigationReactInstance navigationReactInstance;
17
+
18
+    private ReactGateway reactGateway;
21
     private Handler handler;
19
     private Handler handler;
22
 
20
 
23
     @Override
21
     @Override
24
     public void onCreate() {
22
     public void onCreate() {
25
         super.onCreate();
23
         super.onCreate();
26
         instance = this;
24
         instance = this;
25
+        reactGateway = new NavigationReactGateway();
27
         handler = new Handler(getMainLooper());
26
         handler = new Handler(getMainLooper());
28
     }
27
     }
29
 
28
 
29
+    public void startReactContext() {
30
+        reactGateway.startReactContextOnceInBackgroundAndExecuteJS();
31
+    }
32
+
30
     public void runOnMainThread(Runnable runnable) {
33
     public void runOnMainThread(Runnable runnable) {
31
         handler.post(runnable);
34
         handler.post(runnable);
32
     }
35
     }
35
         handler.postDelayed(runnable, delay);
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
     public String getJsEntryFileName() {
49
     public String getJsEntryFileName() {
71
         return "index.android.bundle";
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
     public void sendNavigatorEvent(String eventId, String navigatorEventId) {
63
     public void sendNavigatorEvent(String eventId, String navigatorEventId) {
86
-        if (navigationReactInstance == null) {
64
+        if (!isReactContextInitialized()) {
87
             return;
65
             return;
88
         }
66
         }
89
-        navigationReactInstance.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId);
67
+        reactGateway.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId);
90
     }
68
     }
91
 
69
 
92
     public void sendNavigatorEvent(String eventId, String navigatorEventId, WritableMap data) {
70
     public void sendNavigatorEvent(String eventId, String navigatorEventId, WritableMap data) {
93
-        if (navigationReactInstance == null) {
71
+        if (!isReactContextInitialized()) {
94
             return;
72
             return;
95
         }
73
         }
96
-        navigationReactInstance.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId, data);
74
+        reactGateway.getReactEventEmitter().sendNavigatorEvent(eventId, navigatorEventId, data);
97
     }
75
     }
98
 
76
 
99
     public void sendEvent(String eventId, String navigatorEventId) {
77
     public void sendEvent(String eventId, String navigatorEventId) {
100
-        if (navigationReactInstance == null) {
78
+        if (!isReactContextInitialized()) {
101
             return;
79
             return;
102
         }
80
         }
103
-        navigationReactInstance.getReactEventEmitter().sendEvent(eventId, navigatorEventId);
81
+        reactGateway.getReactEventEmitter().sendEvent(eventId, navigatorEventId);
104
     }
82
     }
105
 
83
 
106
     public void sendNavigatorEvent(String eventId, WritableMap arguments) {
84
     public void sendNavigatorEvent(String eventId, WritableMap arguments) {
107
-        if (navigationReactInstance == null) {
85
+        if (!isReactContextInitialized()) {
108
             return;
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
 import com.reactnativenavigation.params.TitleBarButtonParams;
15
 import com.reactnativenavigation.params.TitleBarButtonParams;
16
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
16
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
17
 import com.reactnativenavigation.react.JsDevReloadHandler;
17
 import com.reactnativenavigation.react.JsDevReloadHandler;
18
-import com.reactnativenavigation.react.NavigationReactInstance;
18
+import com.reactnativenavigation.react.ReactGateway;
19
 import com.reactnativenavigation.react.RedboxPermission;
19
 import com.reactnativenavigation.react.RedboxPermission;
20
 
20
 
21
 import java.util.List;
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
      * Although we start multiple activities, we make sure to pass Intent.CLEAR_TASK | Intent.NEW_TASK
26
      * Although we start multiple activities, we make sure to pass Intent.CLEAR_TASK | Intent.NEW_TASK
39
     @Override
39
     @Override
40
     protected void onCreate(Bundle savedInstanceState) {
40
     protected void onCreate(Bundle savedInstanceState) {
41
         super.onCreate(savedInstanceState);
41
         super.onCreate(savedInstanceState);
42
+
43
+        if (!NavigationApplication.instance.isReactContextInitialized()) {
44
+            NavigationApplication.instance.startReactContext();
45
+            finish();
46
+            return;
47
+        }
48
+
42
         RedboxPermission.permissionToShowRedboxIfNeeded(this);
49
         RedboxPermission.permissionToShowRedboxIfNeeded(this);
43
 
50
 
44
-        activityParams = NavigationCommandsHandler.getActivityParams(getIntent());
51
+        activityParams = NavigationCommandsHandler.parseActivityParams(getIntent());
45
 
52
 
46
         createLayout();
53
         createLayout();
47
         createModalController();
54
         createModalController();
59
     @Override
66
     @Override
60
     protected void onResume() {
67
     protected void onResume() {
61
         super.onResume();
68
         super.onResume();
69
+        if (isFinishing()) {
70
+            return;
71
+        }
72
+
62
         currentActivity = this;
73
         currentActivity = this;
63
-        getNavigationReactInstance().onResume(this, this, this);
74
+        NavigationApplication.instance.getReactGateway().onResume(this, this, this);
64
     }
75
     }
65
 
76
 
66
     @Override
77
     @Override
67
     protected void onPause() {
78
     protected void onPause() {
68
         super.onPause();
79
         super.onPause();
69
         currentActivity = null;
80
         currentActivity = null;
70
-        getNavigationReactInstance().onPause();
81
+        NavigationApplication.instance.getReactGateway().onPause();
71
     }
82
     }
72
 
83
 
73
     @Override
84
     @Override
74
     protected void onDestroy() {
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
         if (currentActivity == null || currentActivity.isFinishing()) {
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
     @Override
100
     @Override
84
     public void onJsDevReload() {
101
     public void onJsDevReload() {
102
+        modalController.destroy();
85
         layout.destroy();
103
         layout.destroy();
86
     }
104
     }
87
 
105
 
93
     @Override
111
     @Override
94
     public void onBackPressed() {
112
     public void onBackPressed() {
95
         if (!layout.onBackPressed()) {
113
         if (!layout.onBackPressed()) {
96
-            getNavigationReactInstance().onBackPressed();
114
+            NavigationApplication.instance.getReactGateway().onBackPressed();
97
         }
115
         }
98
     }
116
     }
99
 
117
 
100
     @Override
118
     @Override
101
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
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
     @Override
123
     @Override
107
         return JsDevReloadHandler.onKeyUp(getCurrentFocus(), keyCode) || super.onKeyUp(keyCode, event);
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
     void push(ScreenParams params) {
128
     void push(ScreenParams params) {
115
         if (modalController.isShowing()) {
129
         if (modalController.isShowing()) {
116
             modalController.push(params);
130
             modalController.push(params);
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
     void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
173
     void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
147
         layout.setTopBarVisible(screenInstanceId, hidden, animated);
174
         layout.setTopBarVisible(screenInstanceId, hidden, animated);
148
         modalController.setTopBarVisible(screenInstanceId, hidden, animated);
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
         if (layout instanceof BottomTabsLayout) {
179
         if (layout instanceof BottomTabsLayout) {
153
             ((BottomTabsLayout) layout).setBottomTabsVisible(hidden, animated);
180
             ((BottomTabsLayout) layout).setBottomTabsVisible(hidden, animated);
154
         }
181
         }
159
         modalController.setTitleBarTitle(screenInstanceId, title);
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
         layout.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
190
         layout.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
164
         modalController.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
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
         layout.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
195
         layout.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
169
         modalController.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
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
 
17
 
18
     private static final String ACTIVITY_PARAMS_BUNDLE = "ACTIVITY_PARAMS_BUNDLE";
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
         return ActivityParamsParser.parse(intent.getBundleExtra(NavigationCommandsHandler.ACTIVITY_PARAMS_BUNDLE));
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
     }
20
     }
21
 
21
 
22
     private static Layout createBottomTabsScreenLayout(AppCompatActivity activity, ActivityParams params) {
22
     private static Layout createBottomTabsScreenLayout(AppCompatActivity activity, ActivityParams params) {
23
+        if (params.tabParams.size() > 5) {
24
+            removeAllButTheFirst5Tabs(params);
25
+        }
23
         return new BottomTabsLayout(activity, params);
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
 
13
 
14
     //TODO yuck.
14
     //TODO yuck.
15
     public static boolean onKeyUp(View currentFocus, int keyCode) {
15
     public static boolean onKeyUp(View currentFocus, int keyCode) {
16
-
17
         ReactInstanceManager reactInstanceManager = NavigationApplication
16
         ReactInstanceManager reactInstanceManager = NavigationApplication
18
                 .instance
17
                 .instance
19
-                .getNavigationReactInstance()
18
+                .getReactGateway()
20
                 .getReactInstanceManager();
19
                 .getReactInstanceManager();
21
 
20
 
22
         if (reactInstanceManager != null &&
21
         if (reactInstanceManager != null &&
40
                                     shouldRefreshOnRR = false;
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
 package com.reactnativenavigation.react;
1
 package com.reactnativenavigation.react;
2
 
2
 
3
+import android.app.Activity;
3
 import android.content.Intent;
4
 import android.content.Intent;
4
 
5
 
5
 import com.facebook.react.LifecycleState;
6
 import com.facebook.react.LifecycleState;
6
 import com.facebook.react.ReactInstanceManager;
7
 import com.facebook.react.ReactInstanceManager;
7
 import com.facebook.react.ReactPackage;
8
 import com.facebook.react.ReactPackage;
9
+import com.facebook.react.bridge.ReactContext;
8
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
10
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
11
+import com.facebook.react.shell.MainReactPackage;
9
 import com.reactnativenavigation.NavigationApplication;
12
 import com.reactnativenavigation.NavigationApplication;
10
 import com.reactnativenavigation.bridge.NavigationReactEventEmitter;
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
     public void startReactContextOnceInBackgroundAndExecuteJS() {
29
     public void startReactContextOnceInBackgroundAndExecuteJS() {
30
+        if (reactInstanceManager == null) {
31
+            reactInstanceManager = createReactInstanceManager();
32
+        }
35
         if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
33
         if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
36
             reactInstanceManager.createReactContextInBackground();
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
     public void onBackPressed() {
54
     public void onBackPressed() {
45
         reactInstanceManager.onBackPressed();
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
     public void onPause() {
64
     public void onPause() {
65
+        reactInstanceManager.onHostPause();
55
         onJsDevReloadListener = null;
66
         onJsDevReloadListener = null;
56
         reactEventEmitter = null;
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
             @Override
82
             @Override
68
             public void onJsDevReload() {
83
             public void onJsDevReload() {
69
                 if (onJsDevReloadListener != null)
84
                 if (onJsDevReloadListener != null)
80
                 .setUseDeveloperSupport(NavigationApplication.instance.isDebug())
95
                 .setUseDeveloperSupport(NavigationApplication.instance.isDebug())
81
                 .setInitialLifecycleState(LifecycleState.BEFORE_RESUME);
96
                 .setInitialLifecycleState(LifecycleState.BEFORE_RESUME);
82
 
97
 
83
-        for (ReactPackage reactPackage : NavigationApplication.instance.createReactPackages()) {
98
+        for (ReactPackage reactPackage : createReactPackages()) {
84
             builder.addPackage(reactPackage);
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

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
 import android.content.Context;
3
 import android.content.Context;
4
 import android.os.Bundle;
4
 import android.os.Bundle;
5
 
5
 
6
-import com.facebook.react.ReactInstanceManager;
7
 import com.facebook.react.ReactRootView;
6
 import com.facebook.react.ReactRootView;
8
 import com.reactnativenavigation.NavigationApplication;
7
 import com.reactnativenavigation.NavigationApplication;
9
 import com.reactnativenavigation.params.ScreenParams;
8
 import com.reactnativenavigation.params.ScreenParams;
40
     }
39
     }
41
 
40
 
42
     private void attachToJS() {
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
     private Bundle mergePropsAndNavigationParams(ScreenParams screenParams, Bundle passProps) {
45
     private Bundle mergePropsAndNavigationParams(ScreenParams screenParams, Bundle passProps) {