Browse Source

react and activity lifecycle race conditions fix

Daniel Zlotin 8 years ago
parent
commit
9cd0788661

+ 1
- 2
android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java View File

50
     public void onReactInitialized(ReactContext reactContext) {
50
     public void onReactInitialized(ReactContext reactContext) {
51
         // nothing
51
         // nothing
52
     }
52
     }
53
-    
53
+
54
     public String getJsEntryFileName() {
54
     public String getJsEntryFileName() {
55
         return "index.android";
55
         return "index.android";
56
     }
56
     }
61
 
61
 
62
     public abstract boolean isDebug();
62
     public abstract boolean isDebug();
63
 
63
 
64
-
65
     @Nullable
64
     @Nullable
66
     public abstract List<ReactPackage> createAdditionalReactPackages();
65
     public abstract List<ReactPackage> createAdditionalReactPackages();
67
 
66
 

+ 17
- 8
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java View File

17
 import com.reactnativenavigation.react.JsDevReloadHandler;
17
 import com.reactnativenavigation.react.JsDevReloadHandler;
18
 import com.reactnativenavigation.react.ReactGateway;
18
 import com.reactnativenavigation.react.ReactGateway;
19
 import com.reactnativenavigation.react.RedboxPermission;
19
 import com.reactnativenavigation.react.RedboxPermission;
20
+import com.reactnativenavigation.utils.IntentUtils;
20
 
21
 
21
 import java.util.List;
22
 import java.util.List;
22
 
23
 
35
     private ActivityParams activityParams;
36
     private ActivityParams activityParams;
36
     private ModalController modalController;
37
     private ModalController modalController;
37
     private Layout layout;
38
     private Layout layout;
39
+    private boolean waitingForNewJsContext = false;
38
 
40
 
39
     @Override
41
     @Override
40
     protected void onCreate(Bundle savedInstanceState) {
42
     protected void onCreate(Bundle savedInstanceState) {
41
         super.onCreate(savedInstanceState);
43
         super.onCreate(savedInstanceState);
42
 
44
 
43
         if (!NavigationApplication.instance.isReactContextInitialized()) {
45
         if (!NavigationApplication.instance.isReactContextInitialized()) {
44
-            NavigationApplication.instance.startReactContext();
46
+            waitingForNewJsContext = true;
45
             finish();
47
             finish();
48
+            startActivity(IntentUtils.getLauncherIntent());
46
             return;
49
             return;
47
         }
50
         }
48
 
51
 
71
         }
74
         }
72
 
75
 
73
         currentActivity = this;
76
         currentActivity = this;
74
-        NavigationApplication.instance.getReactGateway().onResume(this, this, this);
77
+        NavigationApplication.instance.getReactGateway().onResumeActivity(this, this, this);
75
     }
78
     }
76
 
79
 
77
     @Override
80
     @Override
78
     protected void onPause() {
81
     protected void onPause() {
79
         super.onPause();
82
         super.onPause();
80
         currentActivity = null;
83
         currentActivity = null;
81
-        NavigationApplication.instance.getReactGateway().onPause();
84
+        NavigationApplication.instance.getReactGateway().onPauseActivity();
82
     }
85
     }
83
 
86
 
84
     @Override
87
     @Override
85
     protected void onDestroy() {
88
     protected void onDestroy() {
89
+        destroyLayouts();
90
+        destroyJsIfNeeded();
91
+        super.onDestroy();
92
+    }
93
+
94
+    private void destroyLayouts() {
86
         if (modalController != null) {
95
         if (modalController != null) {
87
             modalController.destroy();
96
             modalController.destroy();
88
         }
97
         }
89
         if (layout != null) {
98
         if (layout != null) {
90
             layout.destroy();
99
             layout.destroy();
91
         }
100
         }
92
-        if (currentActivity == null || currentActivity.isFinishing()) {
93
-            if (NavigationApplication.instance.isReactContextInitialized()) {
94
-                NavigationApplication.instance.getReactGateway().onDestroyApp();
95
-            }
101
+    }
102
+
103
+    private void destroyJsIfNeeded() {
104
+        if (!waitingForNewJsContext && (currentActivity == null || currentActivity.isFinishing())) {
105
+            NavigationApplication.instance.getReactGateway().onDestroyApp();
96
         }
106
         }
97
-        super.onDestroy();
98
     }
107
     }
99
 
108
 
100
     @Override
109
     @Override

+ 6
- 0
android/app/src/main/java/com/reactnativenavigation/controllers/SplashActivity.java View File

18
         NavigationApplication.instance.startReactContext();
18
         NavigationApplication.instance.startReactContext();
19
     }
19
     }
20
 
20
 
21
+    @Override
22
+    protected void onPause() {
23
+        super.onPause();
24
+        finish();
25
+    }
26
+
21
     private void setSplashLayout() {
27
     private void setSplashLayout() {
22
         final int splashLayout = getSplashLayout();
28
         final int splashLayout = getSplashLayout();
23
         if (splashLayout > 0) {
29
         if (splashLayout > 0) {

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

64
         reactInstanceManager = null;
64
         reactInstanceManager = null;
65
     }
65
     }
66
 
66
 
67
-    public void onPause() {
67
+    public void onPauseActivity() {
68
         reactInstanceManager.onHostPause();
68
         reactInstanceManager.onHostPause();
69
         onJsDevReloadListener = null;
69
         onJsDevReloadListener = null;
70
     }
70
     }
71
 
71
 
72
-    public void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener) {
72
+    public void onResumeActivity(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener) {
73
         this.onJsDevReloadListener = onJsDevReloadListener;
73
         this.onJsDevReloadListener = onJsDevReloadListener;
74
         reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
74
         reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
75
     }
75
     }

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

24
 
24
 
25
     ReactInstanceManager getReactInstanceManager();
25
     ReactInstanceManager getReactInstanceManager();
26
 
26
 
27
-    void onResume(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener);
27
+    void onResumeActivity(Activity activity, DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler, OnJsDevReloadListener onJsDevReloadListener);
28
 
28
 
29
-    void onPause();
29
+    void onPauseActivity();
30
 
30
 
31
     void onDestroyApp();
31
     void onDestroyApp();
32
 
32
 

+ 19
- 0
android/app/src/main/java/com/reactnativenavigation/utils/IntentUtils.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+import android.content.Intent;
4
+
5
+import com.reactnativenavigation.NavigationApplication;
6
+
7
+public class IntentUtils {
8
+    public static Intent getLauncherIntent() {
9
+        Intent intent = NavigationApplication.instance.getPackageManager().getLaunchIntentForPackage(NavigationApplication.instance.getPackageName());
10
+        if (intent == null)
11
+            intent = new Intent();
12
+        intent.setPackage(null);
13
+        intent.setFlags(0);
14
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
15
+        intent.setAction(Intent.ACTION_MAIN);
16
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
17
+        return intent;
18
+    }
19
+}

+ 10
- 1
example-redux/android/app/src/main/java/com/exampleredux/MainActivity.java View File

1
 package com.exampleredux;
1
 package com.exampleredux;
2
 
2
 
3
+import android.graphics.Color;
4
+import android.view.View;
5
+
3
 import com.reactnativenavigation.controllers.SplashActivity;
6
 import com.reactnativenavigation.controllers.SplashActivity;
4
 
7
 
5
 public class MainActivity extends SplashActivity {
8
 public class MainActivity extends SplashActivity {
6
-    
9
+
10
+    @Override
11
+    public View createSplashLayout() {
12
+        View view = new View(this);
13
+        view.setBackgroundColor(Color.BLUE);
14
+        return view;
15
+    }
7
 }
16
 }

+ 1
- 1
example-redux/android/build.gradle View File

5
         jcenter()
5
         jcenter()
6
     }
6
     }
7
     dependencies {
7
     dependencies {
8
-        classpath 'com.android.tools.build:gradle:2.1.2'
8
+        classpath 'com.android.tools.build:gradle:2.1.3'
9
 
9
 
10
         // NOTE: Do not place your application dependencies here; they belong
10
         // NOTE: Do not place your application dependencies here; they belong
11
         // in the individual module build.gradle files
11
         // in the individual module build.gradle files

+ 2
- 2
example-redux/android/gradle/wrapper/gradle-wrapper.properties View File

1
-#Thu Jun 30 11:51:04 IDT 2016
1
+#Tue Aug 16 15:10:42 IDT 2016
2
 distributionBase=GRADLE_USER_HOME
2
 distributionBase=GRADLE_USER_HOME
3
 distributionPath=wrapper/dists
3
 distributionPath=wrapper/dists
4
 zipStoreBase=GRADLE_USER_HOME
4
 zipStoreBase=GRADLE_USER_HOME
5
 zipStorePath=wrapper/dists
5
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip