expo-modules-core 1.5.11 → 1.5.13
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 +15 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +11 -14
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +25 -13
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +9 -13
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +1 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +15 -19
- package/android/src/main/java/expo/modules/kotlin/viewevent/ViewEvent.kt +22 -5
- package/android/src/main/java/expo/modules/kotlin/viewevent/ViewEventDelegate.kt +3 -11
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +19 -23
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +0 -36
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,21 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 1.5.13 — 2024-01-10
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fixed random `NullPointerExceptions` when calling `Updates.reloadAsync` on Android. ([#24442](https://github.com/expo/expo/pull/24442) by [@lukmccall](https://github.com/lukmccall))
|
|
18
|
+
|
|
19
|
+
## 1.5.12 — 2023-11-17
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- [Android] Improve boot time on low-end devices. ([#25267](https://github.com/expo/expo/pull/25267) by [@lukmccall](https://github.com/lukmccall))
|
|
24
|
+
- [Android] Improve performance of enum and map converters. ([#25272](https://github.com/expo/expo/pull/25272) by [@lukmccall](https://github.com/lukmccall))
|
|
25
|
+
- [Android] Improve logic responsible for obtaining converters that slow down the startup time. ([#25273](https://github.com/expo/expo/pull/25273) by [@lukmccall](https://github.com/lukmccall))
|
|
26
|
+
- [Android] Improving the creation process of views for better performance. ([#25274](https://github.com/expo/expo/pull/25274) by [@lukmccall](https://github.com/lukmccall))
|
|
27
|
+
|
|
13
28
|
## 1.5.11 — 2023-08-29
|
|
14
29
|
|
|
15
30
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
|
|
|
6
6
|
apply plugin: "de.undercouch.download"
|
|
7
7
|
|
|
8
8
|
group = 'host.exp.exponent'
|
|
9
|
-
version = '1.5.
|
|
9
|
+
version = '1.5.13'
|
|
10
10
|
|
|
11
11
|
buildscript {
|
|
12
12
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -160,7 +160,7 @@ android {
|
|
|
160
160
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
161
161
|
consumerProguardFiles 'proguard-rules.pro'
|
|
162
162
|
versionCode 1
|
|
163
|
-
versionName "1.5.
|
|
163
|
+
versionName "1.5.13"
|
|
164
164
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
|
|
165
165
|
|
|
166
166
|
testInstrumentationRunner "expo.modules.TestRunner"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.kotlin
|
|
2
2
|
|
|
3
|
+
import android.view.View
|
|
3
4
|
import expo.modules.kotlin.events.EventName
|
|
4
5
|
import expo.modules.kotlin.modules.Module
|
|
5
6
|
import expo.modules.kotlin.tracing.trace
|
|
@@ -7,9 +8,7 @@ import kotlinx.coroutines.CoroutineName
|
|
|
7
8
|
import kotlinx.coroutines.CoroutineScope
|
|
8
9
|
import kotlinx.coroutines.Dispatchers
|
|
9
10
|
import kotlinx.coroutines.SupervisorJob
|
|
10
|
-
import kotlinx.coroutines.launch
|
|
11
11
|
import java.lang.ref.WeakReference
|
|
12
|
-
import kotlin.reflect.full.declaredMemberProperties
|
|
13
12
|
|
|
14
13
|
class ModuleRegistry(
|
|
15
14
|
private val appContext: WeakReference<AppContext>
|
|
@@ -33,18 +32,6 @@ class ModuleRegistry(
|
|
|
33
32
|
holder.apply {
|
|
34
33
|
post(EventName.MODULE_CREATE)
|
|
35
34
|
registerContracts()
|
|
36
|
-
|
|
37
|
-
// The initial invocation of `declaredMemberProperties` appears to be slow,
|
|
38
|
-
// as Kotlin must deserialize metadata internally.
|
|
39
|
-
// This is a known issue that may be resolved by the new K2 compiler in the future.
|
|
40
|
-
// However, until then, we must find a way to address this problem.
|
|
41
|
-
// Therefore, we have decided to dispatch a lambda
|
|
42
|
-
// that invokes `declaredMemberProperties` during module creation.
|
|
43
|
-
viewClass()?.let { viewType ->
|
|
44
|
-
appContext.get()?.backgroundCoroutineScope?.launch {
|
|
45
|
-
viewType.declaredMemberProperties
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
35
|
}
|
|
49
36
|
|
|
50
37
|
registry[holder.name] = holder
|
|
@@ -70,6 +57,16 @@ class ModuleRegistry(
|
|
|
70
57
|
fun getModuleHolder(module: Module): ModuleHolder? =
|
|
71
58
|
registry.values.find { it.module === module }
|
|
72
59
|
|
|
60
|
+
fun <T : View> getModuleHolder(viewClass: Class<T>): ModuleHolder? {
|
|
61
|
+
return registry.firstNotNullOfOrNull { (_, holder) ->
|
|
62
|
+
if (holder.definition.viewManagerDefinition?.viewType == viewClass) {
|
|
63
|
+
holder
|
|
64
|
+
} else {
|
|
65
|
+
null
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
73
70
|
fun post(eventName: EventName) {
|
|
74
71
|
forEach {
|
|
75
72
|
it.post(eventName)
|
|
@@ -5,24 +5,36 @@ import com.facebook.react.bridge.WritableNativeArray
|
|
|
5
5
|
import com.facebook.react.bridge.WritableNativeMap
|
|
6
6
|
import expo.modules.core.interfaces.DoNotStrip
|
|
7
7
|
import expo.modules.kotlin.exception.UnexpectedException
|
|
8
|
+
import expo.modules.kotlin.logger
|
|
8
9
|
|
|
9
10
|
@Suppress("KotlinJniMissingFunction")
|
|
10
11
|
@DoNotStrip
|
|
11
12
|
class JavaCallback @DoNotStrip internal constructor(@DoNotStrip private val mHybridData: HybridData) : Destructible {
|
|
12
13
|
operator fun invoke(result: Any?) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
try {
|
|
15
|
+
|
|
16
|
+
if (result == null) {
|
|
17
|
+
invoke()
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
when (result) {
|
|
21
|
+
is Int -> invoke(result)
|
|
22
|
+
is Boolean -> invoke(result)
|
|
23
|
+
is Double -> invoke(result)
|
|
24
|
+
is Float -> invoke(result)
|
|
25
|
+
is String -> invoke(result)
|
|
26
|
+
is WritableNativeArray -> invoke(result)
|
|
27
|
+
is WritableNativeMap -> invoke(result)
|
|
28
|
+
else -> throw UnexpectedException("Unknown type: ${result.javaClass}")
|
|
29
|
+
}
|
|
30
|
+
} catch (e: Throwable) {
|
|
31
|
+
if (!mHybridData.isValid) {
|
|
32
|
+
// We know that this particular JavaCallback was invalidated, so it shouldn't be invoked.
|
|
33
|
+
// To prevent crashes, we decided to suppress the error here.
|
|
34
|
+
logger.error("Invalidated JavaCallback was invoked", e)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
throw e
|
|
26
38
|
}
|
|
27
39
|
}
|
|
28
40
|
|
|
@@ -8,8 +8,6 @@ import expo.modules.kotlin.logger
|
|
|
8
8
|
import expo.modules.kotlin.toKType
|
|
9
9
|
import kotlin.reflect.KClass
|
|
10
10
|
import kotlin.reflect.full.createType
|
|
11
|
-
import kotlin.reflect.full.declaredMemberProperties
|
|
12
|
-
import kotlin.reflect.full.isSubclassOf
|
|
13
11
|
import kotlin.reflect.full.primaryConstructor
|
|
14
12
|
|
|
15
13
|
class EnumTypeConverter(
|
|
@@ -29,7 +27,7 @@ class EnumTypeConverter(
|
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
init {
|
|
32
|
-
if (
|
|
30
|
+
if (Enumerable::class.java.isAssignableFrom(enumClass.java)) {
|
|
33
31
|
logger.warn("Enum '$enumClass' should inherit from ${Enumerable::class}.")
|
|
34
32
|
}
|
|
35
33
|
}
|
|
@@ -87,22 +85,20 @@ class EnumTypeConverter(
|
|
|
87
85
|
enumConstants: Array<out Enum<*>>,
|
|
88
86
|
parameterName: String
|
|
89
87
|
): Enum<*> {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
val parameterProperty = enumClass
|
|
93
|
-
.declaredMemberProperties
|
|
94
|
-
.find { it.name == parameterName }
|
|
95
|
-
requireNotNull(parameterProperty) { "Cannot find a property for $parameterName parameter" }
|
|
88
|
+
val filed = enumClass.java.getDeclaredField(parameterName)
|
|
89
|
+
requireNotNull(filed) { "Cannot find a property for $parameterName parameter" }
|
|
96
90
|
|
|
97
|
-
|
|
91
|
+
filed.isAccessible = true
|
|
92
|
+
|
|
93
|
+
val parameterType = filed.type
|
|
98
94
|
val jsUnwrapValue = if (jsValue is Dynamic) {
|
|
99
|
-
if (parameterType == String::class) {
|
|
95
|
+
if (parameterType == String::class.java) {
|
|
100
96
|
jsValue.asString()
|
|
101
97
|
} else {
|
|
102
98
|
jsValue.asInt()
|
|
103
99
|
}
|
|
104
100
|
} else {
|
|
105
|
-
if (parameterType == String::class) {
|
|
101
|
+
if (parameterType == String::class.java) {
|
|
106
102
|
jsValue as String
|
|
107
103
|
} else {
|
|
108
104
|
if (jsValue is Double) {
|
|
@@ -115,7 +111,7 @@ class EnumTypeConverter(
|
|
|
115
111
|
|
|
116
112
|
return requireNotNull(
|
|
117
113
|
enumConstants.find {
|
|
118
|
-
|
|
114
|
+
filed.get(it) == jsUnwrapValue
|
|
119
115
|
}
|
|
120
116
|
) { "Couldn't convert '$jsValue' to ${enumClass.simpleName} where $parameterName is the enum parameter" }
|
|
121
117
|
}
|
|
@@ -10,14 +10,13 @@ import expo.modules.kotlin.exception.exceptionDecorator
|
|
|
10
10
|
import expo.modules.kotlin.jni.ExpectedType
|
|
11
11
|
import expo.modules.kotlin.recycle
|
|
12
12
|
import kotlin.reflect.KType
|
|
13
|
-
import kotlin.reflect.typeOf
|
|
14
13
|
|
|
15
14
|
class MapTypeConverter(
|
|
16
15
|
converterProvider: TypeConverterProvider,
|
|
17
16
|
private val mapType: KType
|
|
18
17
|
) : DynamicAwareTypeConverters<Map<*, *>>(mapType.isMarkedNullable) {
|
|
19
18
|
init {
|
|
20
|
-
require(mapType.arguments.first().type ==
|
|
19
|
+
require(mapType.arguments.first().type?.classifier == String::class) {
|
|
21
20
|
"The map key type should be String, but received ${mapType.arguments.first()}."
|
|
22
21
|
}
|
|
23
22
|
}
|
|
@@ -44,7 +44,6 @@ import java.net.URL
|
|
|
44
44
|
import java.nio.file.Path
|
|
45
45
|
import kotlin.reflect.KClass
|
|
46
46
|
import kotlin.reflect.KType
|
|
47
|
-
import kotlin.reflect.full.isSubclassOf
|
|
48
47
|
import kotlin.reflect.typeOf
|
|
49
48
|
|
|
50
49
|
interface TypeConverterProvider {
|
|
@@ -92,28 +91,25 @@ object TypeConverterProviderImpl : TypeConverterProvider {
|
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
val kClass = type.classifier as? KClass<*> ?: throw MissingTypeConverter(type)
|
|
94
|
+
val jClass = kClass.java
|
|
95
95
|
|
|
96
|
-
if (
|
|
96
|
+
if (jClass.isArray || Array::class.java.isAssignableFrom(jClass)) {
|
|
97
97
|
return ArrayTypeConverter(this, type)
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
if (
|
|
100
|
+
if (List::class.java.isAssignableFrom(jClass)) {
|
|
101
101
|
return ListTypeConverter(this, type)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
if (
|
|
104
|
+
if (Map::class.java.isAssignableFrom(jClass)) {
|
|
105
105
|
return MapTypeConverter(this, type)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
if (
|
|
108
|
+
if (Pair::class.java.isAssignableFrom(jClass)) {
|
|
109
109
|
return PairTypeConverter(this, type)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
if (
|
|
113
|
-
return ArrayTypeConverter(this, type)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (kClass.java.isEnum) {
|
|
112
|
+
if (jClass.isEnum) {
|
|
117
113
|
@Suppress("UNCHECKED_CAST")
|
|
118
114
|
return EnumTypeConverter(kClass as KClass<Enum<*>>, type.isMarkedNullable)
|
|
119
115
|
}
|
|
@@ -123,36 +119,36 @@ object TypeConverterProviderImpl : TypeConverterProvider {
|
|
|
123
119
|
return cachedConverter
|
|
124
120
|
}
|
|
125
121
|
|
|
126
|
-
if (
|
|
122
|
+
if (Record::class.java.isAssignableFrom(jClass)) {
|
|
127
123
|
val converter = RecordTypeConverter<Record>(this, type)
|
|
128
124
|
cachedRecordConverters[kClass] = converter
|
|
129
125
|
return converter
|
|
130
126
|
}
|
|
131
127
|
|
|
132
|
-
if (
|
|
128
|
+
if (View::class.java.isAssignableFrom(jClass)) {
|
|
133
129
|
return ViewTypeConverter<View>(type)
|
|
134
130
|
}
|
|
135
131
|
|
|
136
|
-
if (
|
|
132
|
+
if (SharedObject::class.java.isAssignableFrom(jClass)) {
|
|
137
133
|
return SharedObjectTypeConverter<SharedObject>(type)
|
|
138
134
|
}
|
|
139
135
|
|
|
140
|
-
if (
|
|
136
|
+
if (JavaScriptFunction::class.java.isAssignableFrom(jClass)) {
|
|
141
137
|
return JavaScriptFunctionTypeConverter<Any>(type)
|
|
142
138
|
}
|
|
143
139
|
|
|
144
|
-
return handelEither(type,
|
|
140
|
+
return handelEither(type, jClass)
|
|
145
141
|
?: handelCustomConverter(type, kClass)
|
|
146
142
|
?: throw MissingTypeConverter(type)
|
|
147
143
|
}
|
|
148
144
|
|
|
149
145
|
@OptIn(EitherType::class)
|
|
150
|
-
private fun handelEither(type: KType,
|
|
151
|
-
if (
|
|
152
|
-
if (
|
|
146
|
+
private fun handelEither(type: KType, jClass: Class<*>): TypeConverter<*>? {
|
|
147
|
+
if (Either::class.java.isAssignableFrom(jClass)) {
|
|
148
|
+
if (EitherOfFour::class.java.isAssignableFrom(jClass)) {
|
|
153
149
|
return EitherOfFourTypeConverter<Any, Any, Any, Any>(this, type)
|
|
154
150
|
}
|
|
155
|
-
if (
|
|
151
|
+
if (EitherOfThree::class.java.isAssignableFrom(jClass)) {
|
|
156
152
|
return EitherOfThreeTypeConverter<Any, Any, Any>(this, type)
|
|
157
153
|
}
|
|
158
154
|
return EitherTypeConverter<Any, Any>(this, type)
|
|
@@ -4,22 +4,21 @@ import android.view.View
|
|
|
4
4
|
import com.facebook.react.bridge.ReactContext
|
|
5
5
|
import com.facebook.react.bridge.WritableMap
|
|
6
6
|
import expo.modules.adapters.react.NativeModulesProxy
|
|
7
|
-
import expo.modules.
|
|
7
|
+
import expo.modules.core.utilities.ifNull
|
|
8
|
+
import expo.modules.kotlin.logger
|
|
8
9
|
import expo.modules.kotlin.types.JSTypeConverter
|
|
9
10
|
import expo.modules.kotlin.types.putGeneric
|
|
10
|
-
import kotlin.reflect.KType
|
|
11
11
|
|
|
12
12
|
fun interface ViewEventCallback<T> {
|
|
13
13
|
operator fun invoke(arg: T)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
class ViewEvent<T>(
|
|
16
|
+
open class ViewEvent<T>(
|
|
17
17
|
private val name: String,
|
|
18
|
-
private val type: KType,
|
|
19
18
|
private val view: View,
|
|
20
19
|
private val coalescingKey: CoalescingKey<T>?
|
|
21
20
|
) : ViewEventCallback<T> {
|
|
22
|
-
|
|
21
|
+
private var isValidated = false
|
|
23
22
|
|
|
24
23
|
override operator fun invoke(arg: T) {
|
|
25
24
|
val reactContext = view.context as ReactContext
|
|
@@ -29,6 +28,24 @@ class ViewEvent<T>(
|
|
|
29
28
|
?: return
|
|
30
29
|
val appContext = nativeModulesProxy.kotlinInteropModuleRegistry.appContext
|
|
31
30
|
|
|
31
|
+
if (!isValidated) {
|
|
32
|
+
val holder = appContext.registry.getModuleHolder(view::class.java).ifNull {
|
|
33
|
+
logger.warn("⚠️ Cannot get module holder for ${view::class.java}")
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
val callbacks = holder.definition.viewManagerDefinition?.callbacksDefinition.ifNull {
|
|
37
|
+
logger.warn("⚠️ Cannot get callbacks for ${holder.module::class.java}")
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!callbacks.names.any { it == name }) {
|
|
42
|
+
logger.warn("⚠️ Event $name wasn't exported from ${holder.module::class.java}")
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
isValidated = true
|
|
47
|
+
}
|
|
48
|
+
|
|
32
49
|
appContext
|
|
33
50
|
.callbackInvoker
|
|
34
51
|
?.emit(
|
|
@@ -5,27 +5,19 @@ package expo.modules.kotlin.viewevent
|
|
|
5
5
|
import android.view.View
|
|
6
6
|
import java.lang.ref.WeakReference
|
|
7
7
|
import kotlin.reflect.KProperty
|
|
8
|
-
import kotlin.reflect.KType
|
|
9
|
-
import kotlin.reflect.typeOf
|
|
10
8
|
|
|
11
9
|
typealias CoalescingKey<T> = (event: T) -> Short
|
|
12
10
|
|
|
13
11
|
class ViewEventDelegate<T>(
|
|
14
|
-
private val type: KType,
|
|
15
12
|
view: View,
|
|
16
13
|
private val coalescingKey: CoalescingKey<T>?
|
|
17
14
|
) {
|
|
18
15
|
private val viewHolder = WeakReference(view)
|
|
19
|
-
internal var isValidated = false
|
|
20
16
|
|
|
21
17
|
operator fun getValue(thisRef: View, property: KProperty<*>): ViewEventCallback<T> {
|
|
22
|
-
if (!isValidated) {
|
|
23
|
-
throw IllegalStateException("You have to export '${property.name}' property as a event in the `View` component")
|
|
24
|
-
}
|
|
25
|
-
|
|
26
18
|
val view = viewHolder.get()
|
|
27
19
|
?: throw IllegalStateException("Can't send the '${property.name}' event from the view that is deallocated")
|
|
28
|
-
return ViewEvent(property.name,
|
|
20
|
+
return ViewEvent(property.name, view, coalescingKey)
|
|
29
21
|
}
|
|
30
22
|
}
|
|
31
23
|
|
|
@@ -36,11 +28,11 @@ class ViewEventDelegate<T>(
|
|
|
36
28
|
*/
|
|
37
29
|
@Suppress("FunctionName")
|
|
38
30
|
inline fun <reified T> View.EventDispatcher(noinline coalescingKey: CoalescingKey<T>? = null): ViewEventDelegate<T> {
|
|
39
|
-
return ViewEventDelegate(
|
|
31
|
+
return ViewEventDelegate(this, coalescingKey)
|
|
40
32
|
}
|
|
41
33
|
|
|
42
34
|
@JvmName("MapEventDispatcher")
|
|
43
35
|
@Suppress("FunctionName")
|
|
44
36
|
fun View.EventDispatcher(coalescingKey: CoalescingKey<Map<String, Any>>? = null): ViewEventDelegate<Map<String, Any>> {
|
|
45
|
-
return ViewEventDelegate(
|
|
37
|
+
return ViewEventDelegate(this, coalescingKey)
|
|
46
38
|
}
|
|
@@ -287,41 +287,37 @@ class ViewDefinitionBuilder<T : View>(
|
|
|
287
287
|
) = AsyncFunctionBuilder(name).also { functionBuilders[name] = it }
|
|
288
288
|
|
|
289
289
|
private fun createViewFactory(): (Context, AppContext) -> View = viewFactory@{ context: Context, appContext: AppContext ->
|
|
290
|
-
val
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
val firstArgType = args.first().type
|
|
298
|
-
if (Context::class != firstArgType.classifier) {
|
|
299
|
-
throw IllegalStateException("The type of the first constructor argument has to be `android.content.Context`.")
|
|
290
|
+
val fullConstructor = try {
|
|
291
|
+
// Try to use constructor with two arguments
|
|
292
|
+
viewClass.java.getConstructor(Context::class.java, AppContext::class.java)
|
|
293
|
+
} catch (e: NoSuchMethodException) {
|
|
294
|
+
null
|
|
300
295
|
}
|
|
301
296
|
|
|
302
|
-
|
|
303
|
-
if (args.size == 1) {
|
|
297
|
+
fullConstructor?.let {
|
|
304
298
|
return@viewFactory try {
|
|
305
|
-
|
|
299
|
+
it.newInstance(context, appContext)
|
|
306
300
|
} catch (e: Throwable) {
|
|
307
301
|
handleFailureDuringViewCreation(context, appContext, e)
|
|
308
302
|
}
|
|
309
303
|
}
|
|
310
304
|
|
|
311
|
-
val
|
|
312
|
-
|
|
313
|
-
|
|
305
|
+
val contextConstructor = try {
|
|
306
|
+
// Try to use constructor that use Android's context
|
|
307
|
+
viewClass.java.getConstructor(Context::class.java)
|
|
308
|
+
} catch (e: NoSuchMethodException) {
|
|
309
|
+
null
|
|
314
310
|
}
|
|
315
311
|
|
|
316
|
-
|
|
317
|
-
|
|
312
|
+
contextConstructor?.let {
|
|
313
|
+
return@viewFactory try {
|
|
314
|
+
it.newInstance(context)
|
|
315
|
+
} catch (e: Throwable) {
|
|
316
|
+
handleFailureDuringViewCreation(context, appContext, e)
|
|
317
|
+
}
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
primaryConstructor.call(context, appContext)
|
|
322
|
-
} catch (e: Throwable) {
|
|
323
|
-
handleFailureDuringViewCreation(context, appContext, e)
|
|
324
|
-
}
|
|
320
|
+
throw IllegalStateException("Didn't find a correct constructor for $viewClass")
|
|
325
321
|
}
|
|
326
322
|
|
|
327
323
|
private fun handleFailureDuringViewCreation(context: Context, appContext: AppContext, e: Throwable): View {
|
|
@@ -4,16 +4,12 @@ import android.content.Context
|
|
|
4
4
|
import android.view.View
|
|
5
5
|
import com.facebook.react.bridge.ReadableMap
|
|
6
6
|
import com.facebook.react.common.MapBuilder
|
|
7
|
-
import expo.modules.core.utilities.ifNull
|
|
8
7
|
import expo.modules.kotlin.ModuleHolder
|
|
9
8
|
import expo.modules.kotlin.events.normalizeEventName
|
|
10
9
|
import expo.modules.kotlin.exception.OnViewDidUpdatePropsException
|
|
11
10
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
12
11
|
import expo.modules.kotlin.exception.toCodedException
|
|
13
12
|
import expo.modules.kotlin.logger
|
|
14
|
-
import expo.modules.kotlin.viewevent.ViewEventDelegate
|
|
15
|
-
import kotlin.reflect.full.declaredMemberProperties
|
|
16
|
-
import kotlin.reflect.jvm.isAccessible
|
|
17
13
|
|
|
18
14
|
class ViewManagerWrapperDelegate(internal var moduleHolder: ModuleHolder) {
|
|
19
15
|
private val definition: ViewManagerDefinition
|
|
@@ -31,9 +27,6 @@ class ViewManagerWrapperDelegate(internal var moduleHolder: ModuleHolder) {
|
|
|
31
27
|
fun createView(context: Context): View {
|
|
32
28
|
return definition
|
|
33
29
|
.createView(context, moduleHolder.module.appContext)
|
|
34
|
-
.also {
|
|
35
|
-
configureView(it)
|
|
36
|
-
}
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
fun onViewDidUpdateProps(view: View) {
|
|
@@ -126,33 +119,4 @@ class ViewManagerWrapperDelegate(internal var moduleHolder: ModuleHolder) {
|
|
|
126
119
|
}
|
|
127
120
|
return builder.build()
|
|
128
121
|
}
|
|
129
|
-
|
|
130
|
-
private fun configureView(view: View) {
|
|
131
|
-
val callbacks = definition.callbacksDefinition?.names ?: return
|
|
132
|
-
|
|
133
|
-
val kClass = view.javaClass.kotlin
|
|
134
|
-
val propertiesMap = kClass
|
|
135
|
-
.declaredMemberProperties
|
|
136
|
-
.associateBy { it.name }
|
|
137
|
-
|
|
138
|
-
callbacks.forEach {
|
|
139
|
-
val property = propertiesMap[it].ifNull {
|
|
140
|
-
logger.warn("⚠️ Property `$it` does not exist in ${kClass.simpleName}")
|
|
141
|
-
return@forEach
|
|
142
|
-
}
|
|
143
|
-
property.isAccessible = true
|
|
144
|
-
|
|
145
|
-
val delegate = property.getDelegate(view).ifNull {
|
|
146
|
-
logger.warn("⚠️ Property delegate for `$it` in ${kClass.simpleName} does not exist")
|
|
147
|
-
return@forEach
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
val viewDelegate = (delegate as? ViewEventDelegate<*>).ifNull {
|
|
151
|
-
logger.warn("⚠️ Property delegate for `$it` cannot be cased to `ViewCallbackDelegate`")
|
|
152
|
-
return@forEach
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
viewDelegate.isValidated = true
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
122
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.13",
|
|
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": "^3.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "25af32e83a26dc8027223b61bf7459ba93310ba3"
|
|
46
46
|
}
|