expo-modules-core 0.4.6 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +6 -6
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/adapters/react/apploader/RNHeadlessAppLoader.kt +7 -1
- package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.java +10 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java +14 -0
- package/android/src/main/java/expo/modules/core/interfaces/{ReactNativeHostHandler.kt → ReactNativeHostHandler.java} +20 -15
- package/ios/NativeModulesProxy/EXNativeModulesProxy.m +28 -1
- package/package.json +2 -2
- package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.kt +0 -9
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,30 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.4.10 — 2022-01-05
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fix `ReactInstanceManager.onHostPause` exception from moving Android apps to background. ([#15748](https://github.com/expo/expo/pull/15748) by [@kudo](https://github.com/kudo))
|
|
18
|
+
|
|
19
|
+
## 0.4.9 — 2021-12-08
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- Improve external Android handlers or listeners backward compatibility by Java 8 interface default method. ([#15421](https://github.com/expo/expo/pull/15421) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
25
|
+
## 0.4.8 — 2021-11-11
|
|
26
|
+
|
|
27
|
+
### 🐛 Bug fixes
|
|
28
|
+
|
|
29
|
+
- Fix Gradle error when running Gradle from outside of the project directory. ([#15109](https://github.com/expo/expo/pull/15109) by [@kudo](https://github.com/kudo))
|
|
30
|
+
|
|
31
|
+
## 0.4.7 — 2021-10-28
|
|
32
|
+
|
|
33
|
+
### 🐛 Bug fixes
|
|
34
|
+
|
|
35
|
+
- Fix iOS app freezing in remote debugging mode. ([#14922](https://github.com/expo/expo/pull/14922) by [@kudo](https://github.com/kudo))
|
|
36
|
+
|
|
13
37
|
## 0.4.6 — 2021-10-27
|
|
14
38
|
|
|
15
39
|
_This version does not introduce any user-facing changes._
|
package/README.md
CHANGED
|
@@ -55,23 +55,23 @@ end
|
|
|
55
55
|
```groovy
|
|
56
56
|
// app/build.gradle
|
|
57
57
|
|
|
58
|
-
apply from: new File(["node", "--print", "require.resolve('react-native-unimodules/package.json')"].execute().text.trim(), "../gradle.groovy")
|
|
59
|
-
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute().text.trim(), "../react.gradle")
|
|
60
|
-
apply from: new File(["node", "--print", "require.resolve('expo-updates/package.json')"].execute().text.trim(), "../scripts/create-manifest-android.gradle")
|
|
58
|
+
apply from: new File(["node", "--print", "require.resolve('react-native-unimodules/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy")
|
|
59
|
+
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
|
|
60
|
+
apply from: new File(["node", "--print", "require.resolve('expo-updates/package.json')"].execute(null, rootDir).text.trim(), "../scripts/create-manifest-android.gradle")
|
|
61
61
|
|
|
62
62
|
// ...
|
|
63
63
|
|
|
64
|
-
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute().text.trim(), "../native_modules.gradle");
|
|
64
|
+
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
|
|
65
65
|
applyNativeModulesAppBuildGradle(project)
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
```groovy
|
|
69
69
|
// settings.gradle
|
|
70
70
|
|
|
71
|
-
apply from: new File(["node", "--print", "require.resolve('react-native-unimodules/package.json')"].execute().text.trim(), "../gradle.groovy");
|
|
71
|
+
apply from: new File(["node", "--print", "require.resolve('react-native-unimodules/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy");
|
|
72
72
|
includeUnimodulesProjects()
|
|
73
73
|
|
|
74
|
-
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute().text.trim(), "../native_modules.gradle");
|
|
74
|
+
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
|
|
75
75
|
applyNativeModulesSettingsGradle(settings)
|
|
76
76
|
```
|
|
77
77
|
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '0.4.
|
|
6
|
+
version = '0.4.10'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
// Simple helper that allows the root project to override versions declared by this library.
|
|
@@ -58,7 +58,7 @@ android {
|
|
|
58
58
|
targetSdkVersion safeExtGet("targetSdkVersion", 30)
|
|
59
59
|
consumerProguardFiles 'proguard-rules.pro'
|
|
60
60
|
versionCode 1
|
|
61
|
-
versionName "0.4.
|
|
61
|
+
versionName "0.4.10"
|
|
62
62
|
}
|
|
63
63
|
lintOptions {
|
|
64
64
|
abortOnError false
|
|
@@ -3,6 +3,7 @@ package expo.modules.adapters.react.apploader
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import com.facebook.react.ReactApplication
|
|
5
5
|
import com.facebook.react.ReactInstanceManager
|
|
6
|
+
import com.facebook.react.common.LifecycleState
|
|
6
7
|
import expo.modules.apploader.HeadlessAppLoader
|
|
7
8
|
import expo.modules.core.interfaces.Consumer
|
|
8
9
|
import expo.modules.core.interfaces.DoNotStrip
|
|
@@ -43,7 +44,12 @@ class RNHeadlessAppLoader @DoNotStrip constructor(private val context: Context)
|
|
|
43
44
|
return if (appRecords.containsKey(appScopeKey) && appRecords[appScopeKey] != null) {
|
|
44
45
|
val appRecord: ReactInstanceManager = appRecords[appScopeKey]!!
|
|
45
46
|
android.os.Handler(context.mainLooper).post {
|
|
46
|
-
|
|
47
|
+
// Only destroy the `ReactInstanceManager` if it does not bind with an Activity.
|
|
48
|
+
// And The Activity would take over the ownership of `ReactInstanceManager`.
|
|
49
|
+
// This case happens when a user clicks a background task triggered notification immediately.
|
|
50
|
+
if (appRecord.lifecycleState == LifecycleState.BEFORE_CREATE) {
|
|
51
|
+
appRecord.destroy()
|
|
52
|
+
}
|
|
47
53
|
HeadlessAppLoaderNotifier.notifyAppDestroyed(appScopeKey)
|
|
48
54
|
appRecords.remove(appScopeKey)
|
|
49
55
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package expo.modules.core.interfaces;
|
|
2
|
+
|
|
3
|
+
import android.app.Application;
|
|
4
|
+
import android.content.res.Configuration;
|
|
5
|
+
|
|
6
|
+
public interface ApplicationLifecycleListener {
|
|
7
|
+
default void onCreate(Application application) {}
|
|
8
|
+
|
|
9
|
+
default void onConfigurationChanged(Configuration newConfig) {}
|
|
10
|
+
}
|
package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package expo.modules.core.interfaces;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.os.Bundle;
|
|
5
|
+
|
|
6
|
+
public interface ReactActivityLifecycleListener {
|
|
7
|
+
default void onCreate(Activity activity, Bundle savedInstanceState) {}
|
|
8
|
+
|
|
9
|
+
default void onResume(Activity activity) {}
|
|
10
|
+
|
|
11
|
+
default void onPause(Activity activity) {}
|
|
12
|
+
|
|
13
|
+
default void onDestroy(Activity activity) {}
|
|
14
|
+
}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
package expo.modules.core.interfaces
|
|
1
|
+
package expo.modules.core.interfaces;
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.ReactInstanceManager
|
|
4
|
-
import com.facebook.react.bridge.JavaScriptContextHolder
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
3
|
+
import com.facebook.react.ReactInstanceManager;
|
|
4
|
+
import com.facebook.react.bridge.JavaScriptContextHolder;
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import androidx.annotation.Nullable;
|
|
8
|
+
|
|
9
|
+
public interface ReactNativeHostHandler {
|
|
8
10
|
/**
|
|
9
11
|
* Given chance for modules to customize {@link ReactInstanceManager}
|
|
10
12
|
*
|
|
11
13
|
* @param useDeveloperSupport true if {@link ReactNativeHost} enabled developer support
|
|
12
14
|
* @return instance of {@link ReactInstanceManager}, or null if not to override
|
|
13
15
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
@Nullable
|
|
17
|
+
default ReactInstanceManager createReactInstanceManager(boolean useDeveloperSupport) {
|
|
18
|
+
return null;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -22,8 +25,9 @@ interface ReactNativeHostHandler {
|
|
|
22
25
|
* @param useDeveloperSupport true if {@link ReactNativeHost} enabled developer support
|
|
23
26
|
* @return custom path to bundle file, or null if not to override
|
|
24
27
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
@Nullable
|
|
29
|
+
default String getJSBundleFile(boolean useDeveloperSupport) {
|
|
30
|
+
return null;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
/**
|
|
@@ -33,8 +37,9 @@ interface ReactNativeHostHandler {
|
|
|
33
37
|
* @param useDeveloperSupport true if {@link ReactNativeHost} enabled developer support
|
|
34
38
|
* @return custom bundle asset name, or null if not to override
|
|
35
39
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
@Nullable
|
|
41
|
+
default String getBundleAssetName(boolean useDeveloperSupport) {
|
|
42
|
+
return null;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
/**
|
|
@@ -42,10 +47,10 @@ interface ReactNativeHostHandler {
|
|
|
42
47
|
*
|
|
43
48
|
* @param useDeveloperSupport true if {@link ReactNativeHost} enabled developer support
|
|
44
49
|
*/
|
|
45
|
-
|
|
46
|
-
reactApplicationContext
|
|
47
|
-
jsContext
|
|
48
|
-
useDeveloperSupport
|
|
50
|
+
default void onRegisterJSIModules(
|
|
51
|
+
ReactApplicationContext reactApplicationContext,
|
|
52
|
+
JavaScriptContextHolder jsContext,
|
|
53
|
+
boolean useDeveloperSupport
|
|
49
54
|
) {
|
|
50
55
|
}
|
|
51
56
|
}
|
|
@@ -32,6 +32,7 @@ static const NSString *methodInfoArgumentsCountKey = @"argumentsCount";
|
|
|
32
32
|
|
|
33
33
|
@interface RCTBridge (RegisterAdditionalModuleClasses)
|
|
34
34
|
|
|
35
|
+
- (NSArray<RCTModuleData *> *)registerModulesForClasses:(NSArray<Class> *)moduleClasses;
|
|
35
36
|
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules;
|
|
36
37
|
|
|
37
38
|
@end
|
|
@@ -248,7 +249,7 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
|
|
|
248
249
|
[bridge uiManager];
|
|
249
250
|
|
|
250
251
|
// Register the view managers as additional modules.
|
|
251
|
-
[
|
|
252
|
+
[self registerAdditionalModuleClasses:additionalModuleClasses inBridge:bridge];
|
|
252
253
|
|
|
253
254
|
// Bridge's `registerAdditionalModuleClasses:` method doesn't register
|
|
254
255
|
// components in UIManager — we need to register them on our own.
|
|
@@ -263,6 +264,32 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
|
|
|
263
264
|
[_exModuleRegistry initialize];
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)moduleClasses inBridge:(RCTBridge *)bridge
|
|
268
|
+
{
|
|
269
|
+
// In remote debugging mode, i.e. executorClass is `RCTWebSocketExecutor`,
|
|
270
|
+
// there is a deadlock issue in `registerAdditionalModuleClasses:` and causes app freezed.
|
|
271
|
+
// - The JS thread acquired the `RCTCxxBridge._moduleRegistryLock` lock in `RCTCxxBridge._initializeBridgeLocked`
|
|
272
|
+
// = it further goes into RCTObjcExecutor and tries to get module config from main thread
|
|
273
|
+
// - The main thread is pending in `RCTCxxBridge.registerAdditionalModuleClasses` where trying to acquire the same lock.
|
|
274
|
+
// To workaround the deadlock, we tend to use the non-locked registration and mutate the bridge internal module data.
|
|
275
|
+
// Since JS thread in this situation is waiting for main thread, it's safe to mutate module data without lock.
|
|
276
|
+
// The only risk should be the internal `_moduleRegistryCreated` flag without lock protection.
|
|
277
|
+
// As we just workaround in `RCTWebSocketExecutor` case, the risk of `_moduleRegistryCreated` race condition should be lower.
|
|
278
|
+
//
|
|
279
|
+
// Learn more about the non-locked initialization:
|
|
280
|
+
// https://github.com/facebook/react-native/blob/757bb75fbf837714725d7b2af62149e8e2a7ee51/React/CxxBridge/RCTCxxBridge.mm#L922-L935
|
|
281
|
+
// See the `_moduleRegistryCreated` false case
|
|
282
|
+
if ([NSStringFromClass([bridge executorClass]) isEqualToString:@"RCTWebSocketExecutor"]) {
|
|
283
|
+
NSNumber *moduleRegistryCreated = [bridge valueForKey:@"_moduleRegistryCreated"];
|
|
284
|
+
if (![moduleRegistryCreated boolValue]) {
|
|
285
|
+
[bridge registerModulesForClasses:moduleClasses];
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
[bridge registerAdditionalModuleClasses:moduleClasses];
|
|
291
|
+
}
|
|
292
|
+
|
|
266
293
|
- (void)registerComponentDataForModuleClasses:(NSArray<Class> *)moduleClasses inBridge:(RCTBridge *)bridge
|
|
267
294
|
{
|
|
268
295
|
// Hacky way to get a dictionary with `RCTComponentData` from UIManager.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.10",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"@testing-library/react-hooks": "^7.0.1",
|
|
43
43
|
"expo-module-scripts": "^2.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "94920c7dca7af1747e268c783780d1d2dd3e7a54"
|
|
46
46
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
package expo.modules.core.interfaces
|
|
2
|
-
|
|
3
|
-
import android.app.Application
|
|
4
|
-
import android.content.res.Configuration
|
|
5
|
-
|
|
6
|
-
interface ApplicationLifecycleListener {
|
|
7
|
-
fun onCreate(application: Application) {}
|
|
8
|
-
fun onConfigurationChanged(newConfig: Configuration) {}
|
|
9
|
-
}
|
package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
package expo.modules.core.interfaces
|
|
2
|
-
|
|
3
|
-
import android.app.Activity
|
|
4
|
-
import android.os.Bundle
|
|
5
|
-
|
|
6
|
-
interface ReactActivityLifecycleListener {
|
|
7
|
-
fun onCreate(activity: Activity, savedInstanceState: Bundle?) {}
|
|
8
|
-
fun onResume(activity: Activity) {}
|
|
9
|
-
fun onPause(activity: Activity) {}
|
|
10
|
-
fun onDestroy(activity: Activity) {}
|
|
11
|
-
}
|