AppState

AppState能告诉你应用当前是在前台还是在后台,并且能在状态变化的时候通知你。

AppState 通常在处理推送通知的时候用来决定内容和对应的行为。

App States

  • active - 应用正在前台运行
  • background - 应用正在后台运行。

用户可能面对以下几种情况:

  • 在别的应用中
  • 停留在桌面

对 鸿蒙 来说还可能处在另一个Activity中(即便是由你的应用拉起的), inactive - 此状态表示应用正在前后台的切换过程中,或是处在系统的多任务视图,又或是处在来电状态中。

好的,我们来详细了解一下 React Native 中的 AppState 模块。

AppState 是 React Native 提供的一个核心 API,用于获取和监听应用当前的运行状态(是处于前台还是后台),这对于管理应用资源、处理推送通知、调整界面行为等场景至关重要。

应用状态(App States)

AppState 会报告以下几种状态:

  • active:应用正在前台运行,用户正在与其交互。
  • background:应用正在后台运行。用户可能已经切换到了其他应用、停留在桌面,或者对于 Android 来说,可能正处于另一个 Activity 中(即使是由你的应用拉起的)。
  • inactive:此状态表示应用正在从前台切换到后台,或从后台切换到前台的过程中。它通常是一个过渡状态。
    • 鸿蒙OpenHarmony 特有:在 鸿蒙OpenHarmony 上,当应用处于多任务视图、系统弹出模态框(如来电界面)时,也会进入此状态。
    • 注意:在正常的 React Native 应用中,inactive 状态通常不会持久存在,很快会变为 activebackground

核心属性与方法

  1. currentState
    这是一个静态属性,它会持续保持更新,反映应用当前的实时状态。
console.log(AppState.currentState); // 例如,输出 "active" 或 "background"

重要提示:在应用启动的极短时间内,currentState 可能为 null,直到原生代码通知到状态为止。因此,在应用初始化时需要考虑这个边界情况。

  1. addEventListener(type, listener)
    用于为指定的事件类型添加监听器。当事件发生时,监听器函数会被调用,并传入当前的应用状态。
  • type:事件类型,例如 'change'(状态变化)、'blur'(Android:应用失去焦点)、'focus'(Android:应用获得焦点)、'memoryWarning'(内存警告)。
  • listener:监听器函数,接收当前状态作为参数。
  1. removeEventListener(type, listener)
    用于移除之前添加的监听器,防止内存泄漏。通常在组件卸载时调用。

基本使用示例

下面是一个使用 AppState 的完整示例,展示了如何监听状态变化并更新组件状态:

import React, { useState, useEffect } from 'react';
import { AppState, Text, View, StyleSheet } from 'react-native';

const AppStateMonitor = () => {
  const [currentAppState, setCurrentAppState] = useState(AppState.currentState);

  useEffect(() => {
    // 添加状态变化监听器
    const subscription = AppState.addEventListener('change', handleAppStateChange);

    // 清理函数:组件卸载时移除监听器
    return () => {
      subscription.remove();
    };
  }, []);

  const handleAppStateChange = (nextAppState) => {
    setCurrentAppState(nextAppState);
    console.log('应用状态已切换到:', nextAppState);

    if (nextAppState === 'background') {
      console.log('应用进入后台');
      // 在这里执行进入后台时的逻辑,如暂停定时器、保存数据等
    } else if (nextAppState === 'active') {
      console.log('应用进入前台');
      // 在这里执行进入前台时的逻辑,如恢复定时器、刷新数据等
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.statusText}>
        当前应用状态: {currentAppState}
      </Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'f5fcff',
  },
  statusText: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    fontWeight: 'bold',
  },
});

export default AppStateMonitor;

高级用法与技巧

  1. 精确区分首次启动与后台激活
    一个常见的需求是区分应用的首次启动和从后台重新激活。直接使用 AppState.currentState 无法做到这一点,因为两者在状态变化上看起来是一样的(都是从 background 变为 active)。

解决方案:利用 React 的状态初始化机制。在定义状态变量时,为其设置一个自定义的初始值(如 'startup'),这个值只会在组件首次渲染时存在


真实案例演示:

这段React Native代码实现了一个应用程序状态监听器,其核心功能是实时监控和可视化显示应用在前台、后台或非活动状态之间的切换。代码通过React的响应式编程模型与React Native的AppState模块深度集成,构建了一个能够感知应用生命周期变化的智能组件。

在初始化阶段,组件使用useRef钩子创建了一个持久化的引用对象appState,用于存储当前的应用状态值。这个引用对象在整个组件生命周期内保持稳定,不会因为重新渲染而改变。同时,组件通过useState钩子建立了appStateVisible状态变量,这个变量专门用于驱动UI的重新渲染,确保界面始终与真实的应用状态保持同步。

import React, {useRef, useState, useEffect} from 'react';
import {AppState, StyleSheet, Text, View} from 'react-native';

const AppStateExample = () => {
  const appState = useRef(AppState.currentState);
  const [appStateVisible, setAppStateVisible] = useState(appState.current);

  useEffect(() => {
    const subscription = AppState.addEventListener('change', nextAppState => {
      if (
        appState.current.match(/inactive|background/) &&
        nextAppState === 'active'
      ) {
        console.log('App has come to the foreground!');
      }

      appState.current = nextAppState;
      setAppStateVisible(appState.current);
      console.log('AppState', appState.current);
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return (
    <View style={styles.container}>
      <Text>Current state is: {appStateVisible}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default AppStateExample;

useEffect钩子承担了事件监听的核心职责。它在组件挂载完成后立即执行,通过AppState.addEventListener方法注册一个状态变化监听器。这个监听器会捕获所有应用状态的变更事件,包括从后台切换到前台、从前台切换到后台,或是应用进入非活动状态等场景。监听器函数接收下一个状态值作为参数,并与当前状态进行比较分析,特别关注应用从非活动或后台状态重新回到活动状态的场景,这种场景通常意味着用户重新激活了应用。

在事件处理逻辑中,代码通过正则表达式匹配来检测状态变化的特定模式。当应用从inactive或background状态转变为active状态时,会在控制台输出相应的日志信息,这对于调试和用户行为分析非常有价值。每次状态变化时,appState引用和appStateVisible状态都会同步更新,确保数据的一致性。

视觉反馈方面,组件通过条件渲染技术根据当前的应用状态动态改变文本内容。例如,当应用处于活动状态时,文本显示为"Current state is: active";当应用进入后台时,文本显示为"Current state is: background"。这种动态文本更新机制为用户提供了实时的状态感知能力。

界面布局采用了React Native的弹性布局系统,通过flex: 1属性确保容器始终占据屏幕全屏,并通过justifyContent和alignItems属性实现内容的居中对齐。这种布局设计在不同屏幕尺寸下都能保持良好的视觉效果。
在这里插入图片描述

组件的清理机制也值得关注,在useEffect的返回函数中,代码移除了事件监听器,防止内存泄漏和无效的事件处理。这种设计体现了React组件生命周期管理的最佳实践。

整体来看,这个组件展示了如何在移动应用中实现状态感知和响应式UI更新。它不仅提供了实时的状态监控能力,还通过精心设计的视觉反馈让状态变化变得可见和可理解。这种模式在需要根据应用状态调整行为或界面的场景中非常有用,比如在应用进入后台时暂停游戏、停止媒体播放,或是保存用户数据等操作。


打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

在这里插入图片描述
最后运行效果图如下显示:

请添加图片描述

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐