Преглед на файлове

react and activity lifecycle race conditions fix

Daniel Zlotin преди 8 години
родител
ревизия
9cd0788661

+ 1
- 2
android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java Целия файл

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

+ 17
- 8
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java Целия файл

@@ -17,6 +17,7 @@ import com.reactnativenavigation.params.TitleBarLeftButtonParams;
17 17
 import com.reactnativenavigation.react.JsDevReloadHandler;
18 18
 import com.reactnativenavigation.react.ReactGateway;
19 19
 import com.reactnativenavigation.react.RedboxPermission;
20
+import com.reactnativenavigation.utils.IntentUtils;
20 21
 
21 22
 import java.util.List;
22 23
 
@@ -35,14 +36,16 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
35 36
     private ActivityParams activityParams;
36 37
     private ModalController modalController;
37 38
     private Layout layout;
39
+    private boolean waitingForNewJsContext = false;
38 40
 
39 41
     @Override
40 42
     protected void onCreate(Bundle savedInstanceState) {
41 43
         super.onCreate(savedInstanceState);
42 44
 
43 45
         if (!NavigationApplication.instance.isReactContextInitialized()) {
44
-            NavigationApplication.instance.startReactContext();
46
+            waitingForNewJsContext = true;
45 47
             finish();
48
+            startActivity(IntentUtils.getLauncherIntent());
46 49
             return;
47 50
         }
48 51
 
@@ -71,30 +74,36 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
71 74
         }
72 75
 
73 76
         currentActivity = this;
74
-        NavigationApplication.instance.getReactGateway().onResume(this, this, this);
77
+        NavigationApplication.instance.getReactGateway().onResumeActivity(this, this, this);
75 78
     }
76 79
 
77 80
     @Override
78 81
     protected void onPause() {
79 82
         super.onPause();
80 83
         currentActivity = null;
81
-        NavigationApplication.instance.getReactGateway().onPause();
84
+        NavigationApplication.instance.getReactGateway().onPauseActivity();
82 85
     }
83 86
 
84 87
     @Override
85 88
     protected void onDestroy() {
89
+        destroyLayouts();
90
+        destroyJsIfNeeded();
91
+        super.onDestroy();
92
+    }
93
+
94
+    private void destroyLayouts() {
86 95
         if (modalController != null) {
87 96
             modalController.destroy();
88 97
         }
89 98
         if (layout != null) {
90 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 109
     @Override

+ 6
- 0
android/app/src/main/java/com/reactnativenavigation/controllers/SplashActivity.java Целия файл

@@ -18,6 +18,12 @@ public abstract class SplashActivity extends AppCompatActivity {
18 18
         NavigationApplication.instance.startReactContext();
19 19
     }
20 20
 
21
+    @Override
22
+    protected void onPause() {
23
+        super.onPause();
24
+        finish();
25
+    }
26
+
21 27
     private void setSplashLayout() {
22 28
         final int splashLayout = getSplashLayout();
23 29
         if (splashLayout > 0) {

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/react/NavigationReactGateway.java Целия файл

@@ -64,12 +64,12 @@ public class NavigationReactGateway implements ReactGateway, ReactInstanceManage
64 64
         reactInstanceManager = null;
65 65
     }
66 66
 
67
-    public void onPause() {
67
+    public void onPauseActivity() {
68 68
         reactInstanceManager.onHostPause();
69 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 73
         this.onJsDevReloadListener = onJsDevReloadListener;
74 74
         reactInstanceManager.onHostResume(activity, defaultHardwareBackBtnHandler);
75 75
     }

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/react/ReactGateway.java Целия файл

@@ -24,9 +24,9 @@ public interface ReactGateway {
24 24
 
25 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 31
     void onDestroyApp();
32 32
 

+ 19
- 0
android/app/src/main/java/com/reactnativenavigation/utils/IntentUtils.java Целия файл

@@ -0,0 +1,19 @@
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 Целия файл

@@ -1,7 +1,16 @@
1 1
 package com.exampleredux;
2 2
 
3
+import android.graphics.Color;
4
+import android.view.View;
5
+
3 6
 import com.reactnativenavigation.controllers.SplashActivity;
4 7
 
5 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 Целия файл

@@ -5,7 +5,7 @@ buildscript {
5 5
         jcenter()
6 6
     }
7 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 10
         // NOTE: Do not place your application dependencies here; they belong
11 11
         // in the individual module build.gradle files

+ 2
- 2
example-redux/android/gradle/wrapper/gradle-wrapper.properties Целия файл

@@ -1,6 +1,6 @@
1
-#Thu Jun 30 11:51:04 IDT 2016
1
+#Tue Aug 16 15:10:42 IDT 2016
2 2
 distributionBase=GRADLE_USER_HOME
3 3
 distributionPath=wrapper/dists
4 4
 zipStoreBase=GRADLE_USER_HOME
5 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