You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

前台服务通知点击时根据App前后台/退出状态执行对应逻辑的问题

前台服务通知点击时根据App前后台/退出状态执行对应逻辑的问题

兄弟,我之前用RN Firebase做消息推送的时候,也踩过这个通知点击状态判断的坑,尤其是后台和退出状态下的逻辑区分,确实头疼。结合你说的“JS只触发React方法、原生管服务和通知”的场景,给你分平台捋捋具体怎么搞:

Android端处理

  • 首先在处理通知点击的原生代码里(比如自定义的NotificationReceiver或者前台服务里的通知点击逻辑),先通过ActivityManager判断App的当前状态:
    • App在前台:直接通过React Native的Bridge调用JS的对应方法就行,比如触发你预设的状态回调,把通知携带的参数传过去,JS那边直接执行前台逻辑(比如弹提示、刷新当前页)。
    • App在后台但进程存活:可以先把要执行的逻辑参数存在SharedPreferences里,然后用Intent把App拉到前台,接着在MainActivityonResume或者React上下文的生命周期里读取这个参数,再触发JS的对应逻辑。
    • App已被杀死(进程不存在):点击通知会直接启动MainActivity,你可以在MainActivityonCreate里获取通知携带的extra参数,标记是从通知点击启动的,然后在JS的useEffect(类组件用componentDidMount)里通过原生模块读取这个参数,等App初始化完成后执行对应逻辑。
  • 注意哈,判断App状态别自己瞎维护标记,直接用系统的ActivityManager查最准确,另外前台服务的生命周期别和这个判断冲突,比如服务活着不代表App在前台。

iOS端处理

iOS的通知点击回调分场景处理更清晰:

  • App在前台UNUserNotificationCenterDelegateuserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:方法会触发,这时候直接通过RN桥接把「前台状态」和通知参数传给JS,执行对应逻辑就行。
  • App在后台:同样走这个delegate方法,你可以先通过UIApplication.shared.applicationState判断状态,要是后台的话,先把App拉到前台,再把参数传给JS执行逻辑(iOS后台逻辑限制多,尽量别在后台硬扛复杂操作)。
  • App已退出:点击通知会启动App,这时候在AppDelegatedidFinishLaunchingWithOptions里拿到通知的userInfo,把参数存到UserDefaults里,等RN根组件初始化完成后(比如useEffect里),通过原生模块读取参数,执行启动后的对应逻辑。
  • 额外提一句:iOS13+的通知权限和前台通知设置要配对,不然可能回调不触发,别在这栽跟头。

JS层统一逻辑处理

不管是Android还是iOS,你可以在RN里整个全局的逻辑接收入口:

// 注册原生调用的JS方法,比如通过NativeModules
import { NativeModules, NativeEventEmitter } from 'react-native';

const NotificationEmitter = new NativeEventEmitter(NativeModules.NotificationModule);

// 监听原生传来的通知点击事件
NotificationEmitter.addListener('onNotificationClick', (data) => {
  switch(data.appState) {
    case 'foreground':
      // 前台逻辑:比如显示弹窗、刷新当前页面数据
      console.log('前台点击通知,执行对应操作');
      break;
    case 'background':
      // 后台逻辑:比如跳转到指定详情页
      navigation.navigate('DetailPage', { payload: data.payload });
      break;
    case 'killed':
      // 杀死后启动的逻辑:比如初始化后跳转到指定页面,同时拉取数据
      initAppData().then(() => {
        navigation.navigate('DetailPage', { payload: data.payload });
      });
      break;
  }
});

几个避坑点

  • 原生给JS传参数的时候,一定要用JSON可序列化的格式,别传复杂对象,不然容易出问题。
  • Android的PendingIntent要设对flag,比如用FLAG_UPDATE_CURRENT,确保每次通知点击都能传最新参数,别复用旧的Intent。
  • iOS里在didFinishLaunchingWithOptions拿到参数后,记得及时调用completionHandler,等RN初始化好再传参数,别着急调用JS方法导致报错。

内容来源于stack exchange

火山引擎 最新活动