Page MenuHomePhabricator

D5933.diff
No OneTemporary

D5933.diff

diff --git a/native/expo-modules/android-lifecycle/android/build.gradle b/native/expo-modules/android-lifecycle/android/build.gradle
--- a/native/expo-modules/android-lifecycle/android/build.gradle
+++ b/native/expo-modules/android-lifecycle/android/build.gradle
@@ -88,4 +88,9 @@
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
+
+ implementation "androidx.lifecycle:lifecycle-runtime:2.5.1"
+ implementation "androidx.lifecycle:lifecycle-process:2.5.1"
+
+ implementation 'com.facebook.react:react-native:+'
}
diff --git a/native/expo-modules/android-lifecycle/android/src/main/java/app/comm/android/lifecycle/AndroidLifecycleModule.kt b/native/expo-modules/android-lifecycle/android/src/main/java/app/comm/android/lifecycle/AndroidLifecycleModule.kt
--- a/native/expo-modules/android-lifecycle/android/src/main/java/app/comm/android/lifecycle/AndroidLifecycleModule.kt
+++ b/native/expo-modules/android-lifecycle/android/src/main/java/app/comm/android/lifecycle/AndroidLifecycleModule.kt
@@ -1,38 +1,74 @@
package app.comm.android.lifecycle
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.OnLifecycleEvent
+import androidx.lifecycle.ProcessLifecycleOwner
+import com.facebook.react.bridge.UiThreadUtil
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
+private const val moduleName = "AndroidLifecycle"
+private const val eventName = "LIFECYCLE_CHANGE"
+private const val statusKey = "status"
+
+private enum class LifecycleState(val jsName: String) {
+ ACTIVE("active"),
+ BACKGROUND("background");
+
+ companion object {
+ val constantsMap
+ get() = LifecycleState.values().associate { it.name to it.jsName }
+ }
+}
+
class AndroidLifecycleModule : Module() {
- // Each module class must implement the definition function. The definition consists of components
- // that describes the module's functionality and behavior.
- // See https://docs.expo.dev/modules/module-api for more details about available components.
override fun definition() = ModuleDefinition {
- // Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument.
- // Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
- // The module will be accessible from `requireNativeModule('AndroidLifecycle')` in JavaScript.
- Name("AndroidLifecycle")
-
- // Sets constant properties on the module. Can take a dictionary or a closure that returns a dictionary.
- Constants(
- "PI" to Math.PI
- )
-
- // Defines event names that the module can send to JavaScript.
- Events("onChange")
-
- // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
- Function("hello") {
- "Hello world! 👋"
+ Name(moduleName)
+
+ Constants {
+ val currentState =
+ if (lifecycle.getCurrentState() == Lifecycle.State.RESUMED)
+ LifecycleState.ACTIVE
+ else
+ LifecycleState.BACKGROUND
+ return@Constants LifecycleState.constantsMap +
+ ("initialStatus" to currentState.jsName)
+ }
+
+ Events(eventName)
+
+ OnStartObserving {
+ UiThreadUtil.runOnUiThread {
+ lifecycle.addObserver(observer)
+ }
+ }
+
+ OnStopObserving {
+ UiThreadUtil.runOnUiThread {
+ lifecycle.removeObserver(observer)
+ }
+ }
+ }
+
+ private val lifecycle: Lifecycle
+ get() = ProcessLifecycleOwner.get().getLifecycle()
+
+ private val observer = object : LifecycleObserver {
+ @OnLifecycleEvent(Lifecycle.Event.ON_START)
+ fun onStart() {
+ sendEvent(
+ eventName,
+ mapOf(statusKey to LifecycleState.ACTIVE.jsName)
+ )
}
- // Defines a JavaScript function that always returns a Promise and whose native code
- // is by default dispatched on the different thread than the JavaScript runtime runs on.
- AsyncFunction("setValueAsync") { value: String ->
- // Send an event to JavaScript.
- sendEvent("onChange", mapOf(
- "value" to value
- ))
+ @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+ fun onStop() {
+ sendEvent(
+ eventName,
+ mapOf(statusKey to LifecycleState.BACKGROUND.jsName)
+ )
}
}
}
diff --git a/native/lifecycle/lifecycle-module.js b/native/lifecycle/lifecycle-module.js
--- a/native/lifecycle/lifecycle-module.js
+++ b/native/lifecycle/lifecycle-module.js
@@ -5,32 +5,42 @@
NativeModulesProxy,
EventEmitter,
} from 'expo-modules-core';
+import invariant from 'invariant';
+import { Platform } from 'react-native';
import type { EmitterSubscription } from '../types/react-native';
-const AndroidLifecycleModule: {
- +PI: number,
- +hello: () => string,
- +setValueAsync: string => Promise<void>,
- ...
-} = requireNativeModule('AndroidLifecycle');
-
-export const PI = AndroidLifecycleModule.PI;
+type Active = 'active';
+type Background = 'background';
+type LifecycleStatus = Active | Background;
-export function hello(): string {
- return AndroidLifecycleModule.hello();
-}
-
-export async function setValueAsync(value: string): Promise<void> {
- return await AndroidLifecycleModule.setValueAsync(value);
+let AndroidLifecycleModule: ?{
+ +ACTIVE: Active,
+ +BACKGROUND: Background,
+ +initialStatus: LifecycleStatus,
+ ...
+};
+let emitter;
+if (Platform.OS === 'android') {
+ AndroidLifecycleModule = requireNativeModule('AndroidLifecycle');
+ emitter = new EventEmitter(
+ AndroidLifecycleModule ?? NativeModulesProxy.AndroidLifecycle,
+ );
}
-const emitter = new EventEmitter(
- AndroidLifecycleModule ?? NativeModulesProxy.AndroidLifecycle,
-);
+export const ACTIVE: ?Active = AndroidLifecycleModule?.ACTIVE;
+export const BACKGROUND: ?Background = AndroidLifecycleModule?.BACKGROUND;
+export const initialStatus: ?LifecycleStatus =
+ AndroidLifecycleModule?.initialStatus;
-export function addChangeListener(
- listener: ({ +value: string }) => mixed,
+export function addAndroidLifecycleListener(
+ listener: (state: LifecycleStatus) => mixed,
): EmitterSubscription {
- return emitter.addListener('onChange', listener);
+ invariant(
+ Platform.OS === 'android' && emitter,
+ 'Only Android should call addAndroidLifecycleListener',
+ );
+ return emitter.addListener('LIFECYCLE_CHANGE', ({ status }) =>
+ listener(status),
+ );
}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 1:08 AM (18 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2566971
Default Alt Text
D5933.diff (6 KB)

Event Timeline