Parcourir la source

NavigationApplication, NavigationActivity

Daniel Zlotin il y a 8 ans
Parent
révision
f30ff24da7

+ 23
- 0
android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java Voir le fichier

@@ -0,0 +1,23 @@
1
+package com.reactnativenavigation;
2
+
3
+import android.app.Application;
4
+import android.os.Handler;
5
+
6
+public class NavigationApplication extends Application {
7
+
8
+    public static NavigationApplication instance;
9
+    private Handler handler;
10
+
11
+    @Override
12
+    public void onCreate() {
13
+        super.onCreate();
14
+        instance = this;
15
+        handler = new Handler(getMainLooper());
16
+    }
17
+
18
+    public Handler getMainHandler() {
19
+        return handler;
20
+    }
21
+
22
+
23
+}

+ 174
- 364
android/app/src/main/java/com/reactnativenavigation/activities/BaseReactActivity.java Voir le fichier

@@ -1,47 +1,15 @@
1 1
 package com.reactnativenavigation.activities;
2 2
 
3
-import android.content.Intent;
4
-import android.content.res.Configuration;
5
-import android.os.Build;
6
-import android.os.Bundle;
7
-import android.os.Handler;
8
-import android.provider.Settings;
9
-import android.support.annotation.CallSuper;
10 3
 import android.support.v4.widget.DrawerLayout;
11 4
 import android.support.v7.app.ActionBarDrawerToggle;
12 5
 import android.support.v7.app.AppCompatActivity;
13
-import android.util.Log;
14
-import android.view.KeyEvent;
15 6
 import android.view.Menu;
16
-import android.view.MenuItem;
17
-import android.widget.EditText;
18
-import android.widget.FrameLayout;
19
-import android.widget.Toast;
20 7
 
21
-import com.facebook.common.logging.FLog;
22 8
 import com.facebook.react.ReactInstanceManager;
23
-import com.facebook.react.ReactPackage;
24
-import com.facebook.react.bridge.Arguments;
25
-import com.facebook.react.bridge.ReadableMap;
26
-import com.facebook.react.bridge.WritableMap;
27
-import com.facebook.react.common.ReactConstants;
28 9
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
29
-import com.facebook.react.shell.MainReactPackage;
30
-import com.reactnativenavigation.BuildConfig;
31
-import com.reactnativenavigation.bridge.NavigationReactPackage;
32
-import com.reactnativenavigation.controllers.ModalController;
33
-import com.reactnativenavigation.core.objects.Button;
34
-import com.reactnativenavigation.core.objects.Drawer;
35
-import com.reactnativenavigation.core.objects.Screen;
36
-import com.reactnativenavigation.modal.RnnModal;
37
-import com.reactnativenavigation.utils.ContextProvider;
38
-import com.reactnativenavigation.utils.StyleHelper;
39 10
 import com.reactnativenavigation.views.RnnToolBar;
40 11
 import com.reactnativenavigation.views.ScreenStack;
41 12
 
42
-import java.util.Arrays;
43
-import java.util.List;
44
-
45 13
 import javax.annotation.Nullable;
46 14
 
47 15
 public abstract class BaseReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
@@ -56,346 +24,188 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
56 24
     protected static final String KEY_NAVIGATOR_ID = "navigatorID";
57 25
 
58 26
     private static final String TAG = "BaseReactActivity";
59
-    private static final String REDBOX_PERMISSION_MESSAGE =
60
-            "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
61 27
 
62 28
     @Nullable
63 29
     protected ReactInstanceManager reactInstanceManager;
64
-    private boolean shouldRefreshOnRR = false;
30
+
65 31
     private Menu menu;
66 32
     protected RnnToolBar toolbar;
67 33
     protected ActionBarDrawerToggle drawerToggle;
68 34
     protected DrawerLayout drawerLayout;
69 35
     protected ScreenStack drawerStack;
70 36
 
71
-    /**
72
-     * Returns a list of {@link ReactPackage} used by the app.
73
-     * You'll most likely want to return at least the {@code MainReactPackage}.
74
-     * If your app uses additional views or modules besides the default ones,
75
-     * you'll want to include more packages here.
76
-     */
77
-    public List<ReactPackage> getPackages() {
78
-        return Arrays.asList(
79
-                new MainReactPackage(),
80
-                new NavigationReactPackage()
81
-        );
82
-    }
83
-
84
-    @Override
85
-    protected void onCreate(Bundle savedInstanceState) {
86
-        super.onCreate(savedInstanceState);
87
-        ContextProvider.setActivityContext(this);
88
-        reactInstanceManager = createReactInstanceManager();
89
-        handleOnCreate();
90
-
91
-    }
92
-
93
-    /**
94
-     * A subclass may override this method if it needs to use a custom instance.
95
-     */
96
-    protected ReactInstanceManager createReactInstanceManager() {
97
-        return getReactInstanceManager();
98
-    }
99
-
100
-    protected ReactInstanceManager getReactInstanceManager() {
101
-        RctManager rctManager = RctManager.getInstance();
102
-        if (!rctManager.isInitialized()) {
103
-            rctManager.init(this);
104
-        }
105
-        return rctManager.getReactInstanceManager();
106
-    }
107
-
108
-    @CallSuper
109
-    protected void handleOnCreate() {
110
-        permissionToShowRedboxIfNeeded();
111
-    }
112
-
113
-    private void permissionToShowRedboxIfNeeded() {
114
-        if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
115
-            Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
116
-            startActivity(serviceIntent);
117
-            FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
118
-            Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
119
-        }
120
-    }
121
-
122
-    @Override
123
-    protected void onResume() {
124
-        super.onResume();
125
-        ContextProvider.setActivityContext(this);
126
-
127
-        if (reactInstanceManager != null) {
128
-            reactInstanceManager.onHostResume(this, this);
129
-        }
130
-    }
131
-
132
-    @Override
133
-    protected void onPause() {
134
-        super.onPause();
135
-
136
-        if (reactInstanceManager != null) {
137
-            reactInstanceManager.onHostPause();
138
-        }
139
-
140
-        ContextProvider.clearActivityContext();
141
-    }
142
-
143
-    @Override
144
-    protected void onDestroy() {
145
-        super.onDestroy();
146
-
147
-        // Destroy react instance manager only if there are no resumed react activities
148
-        BaseReactActivity activity = ContextProvider.getActivityContext();
149
-        if (reactInstanceManager != null && (activity == null || activity.isFinishing())) {
150
-            Log.i(TAG, "Destroying ReactInstanceManager");
151
-            reactInstanceManager.onHostDestroy();
152
-            RctManager.getInstance().onDestroy();
153
-        } else {
154
-            Log.d(TAG, "Not destroying ReactInstanceManager");
155
-        }
156
-    }
157
-
158
-    @CallSuper
159
-    public void push(Screen screen) {
160
-        StyleHelper.updateStyles(toolbar, screen);
161
-        if (toolbar != null) {
162
-            toolbar.update(screen);
163
-
164
-            if (getCurrentNavigatorId().equals(screen.navigatorId) &&
165
-                    getScreenStackSize() >= 1) {
166
-                toolbar.setNavUpButton(screen);
167
-            }
168
-        }
169
-    }
170
-
171
-    @CallSuper
172
-    public Screen pop(String navigatorId) {
173
-        if (toolbar != null &&
174
-                getCurrentNavigatorId().equals(navigatorId) &&
175
-                getScreenStackSize() <= 2) {
176
-            toolbar.setNavUpButton();
177
-        }
178
-
179
-        return null;
180
-    }
181
-
182
-    @CallSuper
183
-    public Screen popToRoot(String navigatorId) {
184
-        if (toolbar != null) {
185
-            toolbar.setNavUpButton();
186
-        }
187
-
188
-        return null;
189
-    }
190
-
191
-    @CallSuper
192
-    public Screen resetTo(Screen screen) {
193
-        StyleHelper.updateStyles(toolbar, screen);
194
-        if (toolbar != null) {
195
-            toolbar.setNavUpButton();
196
-        }
197
-
198
-        return null;
199
-    }
200
-
201
-    protected abstract String getCurrentNavigatorId();
202
-
203
-    @CallSuper
204
-    public Screen getCurrentScreen() {
205
-        ModalController modalController = ModalController.getInstance();
206
-        if (modalController.isModalDisplayed()) {
207
-            RnnModal modal = modalController.get();
208
-            assert modal != null;
209
-            return modal.getCurrentScreen();
210
-        }
211
-
212
-        return null;
213
-    }
214
-
215
-    public abstract int getScreenStackSize();
216
-
217
-    @Override
218
-    public void onConfigurationChanged(Configuration newConfig) {
219
-        super.onConfigurationChanged(newConfig);
220
-        if (drawerToggle != null) {
221
-            drawerToggle.onConfigurationChanged(newConfig);
222
-        }
223
-    }
224
-
225
-    @Override
226
-    public boolean onCreateOptionsMenu(Menu menu) {
227
-        this.menu = menu;
228
-        Screen currentScreen = getCurrentScreen();
229
-        if (toolbar != null && currentScreen != null && !isFinishing()) {
230
-            toolbar.setupToolbarButtonsAsync(currentScreen);
231
-        }
232
-        return super.onCreateOptionsMenu(menu);
233
-    }
234
-
235
-    @Override
236
-    public boolean onOptionsItemSelected(MenuItem item) {
237
-        if (drawerToggle != null &&
238
-                getScreenStackSize() == 1 &&
239
-                drawerToggle.onOptionsItemSelected(item)) {
240
-            return true;
241
-        }
242
-
243
-        if (item.getItemId() == android.R.id.home) {
244
-            onBackPressed();
245
-        } else {
246
-            String eventId = Button.getButtonEventId(item);
247
-            assert eventId != null;
248
-
249
-            WritableMap params = Arguments.createMap();
250
-            RctManager.getInstance().sendEvent(eventId, getCurrentScreen(), params);
251
-        }
252
-        return super.onOptionsItemSelected(item);
253
-    }
254
-
255
-    @Override
256
-    public void onPostCreate(Bundle savedInstanceState) {
257
-        super.onPostCreate(savedInstanceState);
258
-        if (drawerToggle != null) {
259
-            drawerToggle.syncState();
260
-        }
261
-    }
262
-
263
-    public Menu getMenu() {
264
-        return menu;
265
-    }
266
-
267
-    @Override
268
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
269
-        if (reactInstanceManager != null) {
270
-            reactInstanceManager.onActivityResult(requestCode, resultCode, data);
271
-        }
272
-    }
273
-
274
-    @Override
275
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
276
-        if (reactInstanceManager != null &&
277
-                reactInstanceManager.getDevSupportManager().getDevSupportEnabled()) {
278
-            if (keyCode == KeyEvent.KEYCODE_MENU) {
279
-                reactInstanceManager.showDevOptionsDialog();
280
-                return true;
281
-            }
282
-            if (keyCode == KeyEvent.KEYCODE_R && !(getCurrentFocus() instanceof EditText)) {
283
-                // Enable double-tap-R-to-reload
284
-                if (shouldRefreshOnRR) {
285
-                    reactInstanceManager.getDevSupportManager().handleReloadJS();
286
-                    shouldRefreshOnRR = false;
287
-                } else {
288
-                    shouldRefreshOnRR = true;
289
-                    new Handler().postDelayed(
290
-                            new Runnable() {
291
-                                @Override
292
-                                public void run() {
293
-                                    shouldRefreshOnRR = false;
294
-                                }
295
-                            },
296
-                            200);
297
-                }
298
-            }
299
-        }
300
-        return super.onKeyUp(keyCode, event);
301
-    }
302
-
303
-    /**
304
-     * Called after bundle was reloaded. This is a good chance to clean up previously connected react views.
305
-     */
306
-    public void onJSBundleReloaded() {
307
-        removeAllReactViews();
308
-    }
309
-
310
-    protected abstract void removeAllReactViews();
311
-
312
-    @Override
313
-    public void onBackPressed() {
314
-        ModalController modalController = ModalController.getInstance();
315
-        if (modalController.isModalDisplayed()) {
316
-            modalController.dismissModal();
317
-            return;
318
-        }
319
-
320
-        if (getScreenStackSize() > 1) {
321
-            pop(getCurrentNavigatorId());
322
-        } else if (reactInstanceManager != null) {
323
-            reactInstanceManager.onBackPressed();
324
-        } else {
325
-            super.onBackPressed();
326
-        }
327
-    }
328
-
329
-    @Override
330
-    public void invokeDefaultOnBackPressed() {
331
-        super.onBackPressed();
332
-    }
333
-
334
-    protected void setupDrawer(Screen screen, Drawer drawer, int drawerFrameId, int drawerLayoutId) {
335
-        if (drawer == null || drawer.left == null) {
336
-            return;
337
-        }
338
-
339
-        drawerStack = new ScreenStack(this);
340
-        FrameLayout drawerFrame = (FrameLayout) findViewById(drawerFrameId);
341
-        drawerFrame.addView(drawerStack);
342
-        drawerStack.push(drawer.left);
343
-
344
-        drawerLayout = (DrawerLayout) findViewById(drawerLayoutId);
345
-        drawerToggle = toolbar.setupDrawer(drawerLayout, drawer.left, screen);
346
-    }
347
-
348
-    public void setNavigationButtons(ReadableMap buttons) {
349
-        if (toolbar == null) {
350
-            return;
351
-        }
352
-        getCurrentScreen().setButtons(buttons);
353
-        toolbar.setupToolbarButtonsAsync(getCurrentScreen());
354
-    }
355
-
356
-    public void setNavigationTitle(ReadableMap title) {
357
-        if (toolbar == null) {
358
-            return;
359
-        }
360
-
361
-        toolbar.setTitle(title.getString(KEY_TITLE));
362
-    }
363
-
364
-    public void toggleNavigationBar(ReadableMap params) {
365
-        if (toolbar == null) {
366
-            return;
367
-        }
368
-
369
-        boolean hide = params.getBoolean(KEY_HIDDEN);
370
-        boolean animated = params.getBoolean(KEY_ANIMATED);
371
-        if (hide) {
372
-            toolbar.hideToolbar(animated);
373
-        } else {
374
-            toolbar.showToolbar(animated);
375
-        }
376
-    }
377
-
378
-    public void toggleDrawer(ReadableMap params) {
379
-        if (toolbar == null || drawerToggle == null) {
380
-            return;
381
-        }
382
-
383
-        boolean animated = params.getBoolean(KEY_ANIMATED);
384
-        String side = params.getString(KEY_SIDE);
385
-        String to = params.getString(KEY_TO);
386
-        switch (to) {
387
-            case "open":
388
-                toolbar.showDrawer(animated);
389
-                break;
390
-            case "closed":
391
-                toolbar.hideDrawer(animated);
392
-                break;
393
-            default:
394
-                toolbar.toggleDrawer(animated);
395
-                break;
396
-        }
397
-    }
398 37
 
399
-    public void showFAB(ReadableMap params) {
400
-    }
38
+//    @CallSuper
39
+//    public void push(Screen screen) {
40
+//        StyleHelper.updateStyles(toolbar, screen);
41
+//        if (toolbar != null) {
42
+//            toolbar.update(screen);
43
+//
44
+//            if (getCurrentNavigatorId().equals(screen.navigatorId) &&
45
+//                    getScreenStackSize() >= 1) {
46
+//                toolbar.setNavUpButton(screen);
47
+//            }
48
+//        }
49
+//    }
50
+
51
+//    @CallSuper
52
+//    public Screen pop(String navigatorId) {
53
+//        if (toolbar != null &&
54
+//                getCurrentNavigatorId().equals(navigatorId) &&
55
+//                getScreenStackSize() <= 2) {
56
+//            toolbar.setNavUpButton();
57
+//        }
58
+//
59
+//        return null;
60
+//    }
61
+//
62
+//    @CallSuper
63
+//    public Screen popToRoot(String navigatorId) {
64
+//        if (toolbar != null) {
65
+//            toolbar.setNavUpButton();
66
+//        }
67
+//
68
+//        return null;
69
+//    }
70
+//
71
+//    @CallSuper
72
+//    public Screen resetTo(Screen screen) {
73
+//        StyleHelper.updateStyles(toolbar, screen);
74
+//        if (toolbar != null) {
75
+//            toolbar.setNavUpButton();
76
+//        }
77
+//
78
+//        return null;
79
+//    }
80
+
81
+//    @CallSuper
82
+//    public Screen getCurrentScreen() {
83
+//        ModalController modalController = ModalController.getInstance();
84
+//        if (modalController.isModalDisplayed()) {
85
+//            RnnModal modal = modalController.get();
86
+//            assert modal != null;
87
+//            return modal.getCurrentScreen();
88
+//        }
89
+//
90
+//        return null;
91
+//    }
92
+
93
+//    @Override
94
+//    public void onConfigurationChanged(Configuration newConfig) {
95
+//        super.onConfigurationChanged(newConfig);
96
+//        if (drawerToggle != null) {
97
+//            drawerToggle.onConfigurationChanged(newConfig);
98
+//        }
99
+//    }
100
+
101
+//    @Override
102
+//    public boolean onCreateOptionsMenu(Menu menu) {
103
+//        this.menu = menu;
104
+//        Screen currentScreen = getCurrentScreen();
105
+//        if (toolbar != null && currentScreen != null && !isFinishing()) {
106
+//            toolbar.setupToolbarButtonsAsync(currentScreen);
107
+//        }
108
+//        return super.onCreateOptionsMenu(menu);
109
+//    }
110
+
111
+//    @Override
112
+//    public boolean onOptionsItemSelected(MenuItem item) {
113
+//        if (drawerToggle != null &&
114
+//                getScreenStackSize() == 1 &&
115
+//                drawerToggle.onOptionsItemSelected(item)) {
116
+//            return true;
117
+//        }
118
+//
119
+//        if (item.getItemId() == android.R.id.home) {
120
+//            onBackPressed();
121
+//        } else {
122
+//            String eventId = Button.getButtonEventId(item);
123
+//            assert eventId != null;
124
+//
125
+//            WritableMap params = Arguments.createMap();
126
+//            RctManager.getInstance().sendEvent(eventId, getCurrentScreen(), params);
127
+//        }
128
+//        return super.onOptionsItemSelected(item);
129
+//    }
130
+
131
+//    @Override
132
+//    public void onPostCreate(Bundle savedInstanceState) {
133
+//        super.onPostCreate(savedInstanceState);
134
+//        if (drawerToggle != null) {
135
+//            drawerToggle.syncState();
136
+//        }
137
+//    }
138
+
139
+//    public Menu getMenu() {
140
+//        return menu;
141
+//    }
142
+
143
+
144
+//    protected void setupDrawer(Screen screen, Drawer drawer, int drawerFrameId, int drawerLayoutId) {
145
+//        if (drawer == null || drawer.left == null) {
146
+//            return;
147
+//        }
148
+//
149
+//        drawerStack = new ScreenStack(this);
150
+//        FrameLayout drawerFrame = (FrameLayout) findViewById(drawerFrameId);
151
+//        drawerFrame.addView(drawerStack);
152
+//        drawerStack.push(drawer.left);
153
+//
154
+//        drawerLayout = (DrawerLayout) findViewById(drawerLayoutId);
155
+//        drawerToggle = toolbar.setupDrawer(drawerLayout, drawer.left, screen);
156
+//    }
157
+
158
+//    public void setNavigationButtons(ReadableMap buttons) {
159
+//        if (toolbar == null) {
160
+//            return;
161
+//        }
162
+//        getCurrentScreen().setButtons(buttons);
163
+//        toolbar.setupToolbarButtonsAsync(getCurrentScreen());
164
+//    }
165
+//
166
+//    public void setNavigationTitle(ReadableMap title) {
167
+//        if (toolbar == null) {
168
+//            return;
169
+//        }
170
+//
171
+//        toolbar.setTitle(title.getString(KEY_TITLE));
172
+//    }
173
+
174
+//    public void toggleNavigationBar(ReadableMap params) {
175
+//        if (toolbar == null) {
176
+//            return;
177
+//        }
178
+//
179
+//        boolean hide = params.getBoolean(KEY_HIDDEN);
180
+//        boolean animated = params.getBoolean(KEY_ANIMATED);
181
+//        if (hide) {
182
+//            toolbar.hideToolbar(animated);
183
+//        } else {
184
+//            toolbar.showToolbar(animated);
185
+//        }
186
+//    }
187
+
188
+//    public void toggleDrawer(ReadableMap params) {
189
+//        if (toolbar == null || drawerToggle == null) {
190
+//            return;
191
+//        }
192
+//
193
+//        boolean animated = params.getBoolean(KEY_ANIMATED);
194
+//        String side = params.getString(KEY_SIDE);
195
+//        String to = params.getString(KEY_TO);
196
+//        switch (to) {
197
+//            case "open":
198
+//                toolbar.showDrawer(animated);
199
+//                break;
200
+//            case "closed":
201
+//                toolbar.hideDrawer(animated);
202
+//                break;
203
+//            default:
204
+//                toolbar.toggleDrawer(animated);
205
+//                break;
206
+//        }
207
+//    }
208
+//
209
+//    public void showFAB(ReadableMap params) {
210
+//    }
401 211
 }

+ 93
- 10
android/app/src/main/java/com/reactnativenavigation/activities/NavigationActivity.java Voir le fichier

@@ -1,33 +1,116 @@
1 1
 package com.reactnativenavigation.activities;
2 2
 
3
+import android.app.Activity;
4
+import android.content.Intent;
5
+import android.os.Build;
3 6
 import android.os.Bundle;
7
+import android.provider.Settings;
8
+import android.support.v7.app.AppCompatActivity;
9
+import android.util.Log;
10
+import android.view.KeyEvent;
11
+import android.widget.Toast;
4 12
 
5
-public class NavigationActivity extends BaseReactActivity {
13
+import com.facebook.react.ReactPackage;
14
+import com.facebook.react.common.ReactConstants;
15
+import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
16
+import com.facebook.react.shell.MainReactPackage;
17
+import com.reactnativenavigation.BuildConfig;
18
+import com.reactnativenavigation.bridge.NavigationReactPackage;
19
+import com.reactnativenavigation.controllers.ModalController;
20
+import com.reactnativenavigation.react.JsDevReloadHandler;
21
+import com.reactnativenavigation.react.NavigationReactInstance;
22
+
23
+import java.util.Arrays;
24
+import java.util.List;
25
+
26
+
27
+public class NavigationActivity extends AppCompatActivity implements NavigationReactInstance.ReactContextCreator, DefaultHardwareBackBtnHandler {
28
+
29
+    private NavigationReactInstance navigationReactInstance;
30
+    private static Activity currentActivity;
6 31
 
7 32
     @Override
8 33
     protected void onCreate(Bundle savedInstanceState) {
9 34
         super.onCreate(savedInstanceState);
10
-        startReactContextOnceInBackgroundAndExecuteJS();
35
+        navigationReactInstance = new NavigationReactInstance(this);
36
+        navigationReactInstance.startReactContextOnceInBackgroundAndExecuteJS();
37
+        permissionToShowRedboxIfNeeded();
38
+    }
39
+
40
+    @Override
41
+    protected void onResume() {
42
+        super.onResume();
43
+        currentActivity = this;
44
+        navigationReactInstance.onResume(this, this);
45
+    }
46
+
47
+    @Override
48
+    protected void onPause() {
49
+        super.onPause();
50
+        currentActivity = null;
51
+        navigationReactInstance.onPause();
52
+    }
53
+
54
+    @Override
55
+    protected void onDestroy() {
56
+        super.onDestroy();
57
+        if (currentActivity == null || currentActivity.isFinishing()) {
58
+            navigationReactInstance.onHostDestroy();
59
+        }
11 60
     }
12 61
 
13
-    private void startReactContextOnceInBackgroundAndExecuteJS() {
14
-        if (!getReactInstanceManager().hasStartedCreatingInitialContext()) {
15
-            getReactInstanceManager().createReactContextInBackground();
62
+    private void permissionToShowRedboxIfNeeded() {
63
+        if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
64
+            Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
65
+            startActivity(serviceIntent);
66
+            String msg = "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
67
+            Log.w(ReactConstants.TAG, msg);
68
+            Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
16 69
         }
17 70
     }
18 71
 
72
+    private NavigationReactInstance getNavigationReactInstance() {
73
+        return navigationReactInstance;
74
+    }
75
+
19 76
     @Override
20
-    protected String getCurrentNavigatorId() {
21
-        return null;
77
+    public List<ReactPackage> createReactPackages() {
78
+        return Arrays.asList(
79
+                new MainReactPackage(),
80
+                new NavigationReactPackage()
81
+        );
22 82
     }
23 83
 
24 84
     @Override
25
-    public int getScreenStackSize() {
26
-        return 0;
85
+    public void onJsDevReload() {
86
+        layout.removeAllReactViews();
27 87
     }
28 88
 
29 89
     @Override
30
-    protected void removeAllReactViews() {
90
+    public void invokeDefaultOnBackPressed() {
91
+        super.onBackPressed();
92
+    }
93
+
31 94
 
95
+    @Override
96
+    public void onBackPressed() {
97
+        if (modalController.onBackPressed()) {
98
+            return;
99
+        }
100
+        if (layout.onBackPressed()) {
101
+            return;
102
+        }
103
+        navigationReactInstance.onBackPressed();
104
+    }
105
+
106
+    @Override
107
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
108
+        navigationReactInstance.onActivityResult(requestCode, resultCode, data);
109
+    }
110
+
111
+    @Override
112
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
113
+        return JsDevReloadHandler.onKeyUp(navigationReactInstance.getReactInstanceManager(), getCurrentFocus(), keyCode)
114
+                || super.onKeyUp(keyCode, event);
32 115
     }
33 116
 }

+ 2
- 3
android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactEventEmitter.java Voir le fichier

@@ -1,7 +1,7 @@
1 1
 package com.reactnativenavigation.bridge;
2 2
 
3 3
 import com.facebook.react.bridge.WritableMap;
4
-import com.facebook.react.modules.core.DeviceEventManagerModule;
4
+import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
5 5
 import com.reactnativenavigation.core.objects.Screen;
6 6
 
7 7
 public class NavigationReactEventEmitter {
@@ -10,8 +10,7 @@ public class NavigationReactEventEmitter {
10 10
     private static final String KEY_EVENT_TYPE = "type";
11 11
     private static final String EVENT_TYPE = "NavBarButtonPress";
12 12
 
13
-    public void sendEvent(String eventName, String navigatorEventId, WritableMap params) {
14
-        DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter = getEventEmitter();
13
+    public void sendEvent(RCTDeviceEventEmitter eventEmitter, String eventName, String navigatorEventId, WritableMap params) {
15 14
         if (eventEmitter == null) {
16 15
             return;
17 16
         }

+ 43
- 0
android/app/src/main/java/com/reactnativenavigation/react/JsDevReloadHandler.java Voir le fichier

@@ -0,0 +1,43 @@
1
+package com.reactnativenavigation.react;
2
+
3
+import android.view.KeyEvent;
4
+import android.view.View;
5
+import android.widget.EditText;
6
+
7
+import com.facebook.react.ReactInstanceManager;
8
+import com.reactnativenavigation.NavigationApplication;
9
+
10
+public class JsDevReloadHandler {
11
+
12
+    private static boolean shouldRefreshOnRR = false;
13
+
14
+    //TODO yuck.
15
+    public static boolean onKeyUp(ReactInstanceManager reactInstanceManager, View currentFocus, int keyCode) {
16
+        if (reactInstanceManager != null &&
17
+                reactInstanceManager.getDevSupportManager().getDevSupportEnabled()) {
18
+            if (keyCode == KeyEvent.KEYCODE_MENU) {
19
+                reactInstanceManager.showDevOptionsDialog();
20
+                return true;
21
+            }
22
+            if (keyCode == KeyEvent.KEYCODE_R && !(currentFocus instanceof EditText)) {
23
+                // Enable double-tap-R-to-reload
24
+                if (shouldRefreshOnRR) {
25
+                    reactInstanceManager.getDevSupportManager().handleReloadJS();
26
+                    shouldRefreshOnRR = false;
27
+                    return true;
28
+                } else {
29
+                    shouldRefreshOnRR = true;
30
+                    NavigationApplication.instance.getMainHandler().postDelayed(
31
+                            new Runnable() {
32
+                                @Override
33
+                                public void run() {
34
+                                    shouldRefreshOnRR = false;
35
+                                }
36
+                            },
37
+                            200);
38
+                }
39
+            }
40
+        }
41
+        return false;
42
+    }
43
+}

+ 36
- 5
android/app/src/main/java/com/reactnativenavigation/react/NavigationReactInstance.java Voir le fichier

@@ -1,13 +1,16 @@
1 1
 package com.reactnativenavigation.react;
2 2
 
3
-import android.app.Application;
3
+import android.app.Activity;
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;
8 9
 import com.facebook.react.bridge.ReactContext;
10
+import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
9 11
 import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
10 12
 import com.reactnativenavigation.BuildConfig;
13
+import com.reactnativenavigation.NavigationApplication;
11 14
 
12 15
 import java.util.List;
13 16
 
@@ -16,8 +19,6 @@ public class NavigationReactInstance {
16 19
     private final ReactInstanceManager reactInstanceManager;
17 20
 
18 21
     public interface ReactContextCreator {
19
-        Application getApplication();
20
-
21 22
         List<ReactPackage> createReactPackages();
22 23
 
23 24
         void onJsDevReload();
@@ -31,7 +32,17 @@ public class NavigationReactInstance {
31 32
         }
32 33
     }
33 34
 
34
-    private RCTDeviceEventEmitter getEventEmitter() {
35
+    public ReactInstanceManager getReactInstanceManager() {
36
+        return reactInstanceManager;
37
+    }
38
+
39
+    public void startReactContextOnceInBackgroundAndExecuteJS() {
40
+        if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
41
+            reactInstanceManager.createReactContextInBackground();
42
+        }
43
+    }
44
+
45
+    public RCTDeviceEventEmitter getEventEmitter() {
35 46
         ReactContext currentReactContext = reactInstanceManager.getCurrentReactContext();
36 47
         if (currentReactContext == null) {
37 48
             return null;
@@ -40,6 +51,26 @@ public class NavigationReactInstance {
40 51
         return currentReactContext.getJSModule(RCTDeviceEventEmitter.class);
41 52
     }
42 53
 
54
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
55
+        reactInstanceManager.onActivityResult(requestCode, resultCode, data);
56
+    }
57
+
58
+    public void onBackPressed() {
59
+        reactInstanceManager.onBackPressed();
60
+    }
61
+
62
+    public void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler) {
63
+        reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
64
+    }
65
+
66
+    public void onPause() {
67
+        reactInstanceManager.onHostPause();
68
+    }
69
+
70
+    public void onHostDestroy() {
71
+        reactInstanceManager.onHostDestroy();
72
+    }
73
+
43 74
     private void replaceJsDevReloadListener(final ReactContextCreator reactContextCreator) {
44 75
         new JsDevReloadListenerReplacer(reactInstanceManager, new JsDevReloadListenerReplacer.Listener() {
45 76
             @Override
@@ -51,7 +82,7 @@ public class NavigationReactInstance {
51 82
 
52 83
     private ReactInstanceManager createReactInstanceManager(final ReactContextCreator reactContextCreator) {
53 84
         ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
54
-                .setApplication(reactContextCreator.getApplication())
85
+                .setApplication(NavigationApplication.instance)
55 86
                 .setJSMainModuleName("index.android")
56 87
                 .setBundleAssetName("index.android.bundle")
57 88
                 .setUseDeveloperSupport(BuildConfig.DEBUG)