web-dev-qa-db-ja.com

React Native、Androidライフサイクルとナビゲーション

React redux-persistを使用して、ナビゲーション状態を含むアプリの状態を保存するネイティブアプリを構築しています。このアプリをナビゲーションの観点からネイティブアプリのように動作させたいと思います。

ネイティブAndroidアプリがバックグラウンドになり、最終的にOSによって停止されてからフォアグラウンドに移動されると、ユーザーが以前に中断したアクティビティで再開されます。同じアプリの場合ユーザーによって殺された(またはクラッシュした)場合、メインアクティビティで開きます。

RNアプリの場合、これは、アプリがユーザーによって強制終了されなかった場合に限り、redux-persistがアプリのcomponentWillMountのナビゲーション状態を永続化および復元する必要があることを意味します。

次のコードが機能します。

componentWillMount() {
  if (global.isRelaunch) {
    // purge redux-persist navigation state
  }
  global.isRelaunch = true;
...

しかし、それはハックっぽく見え、グローバルスコープが生き残る理由もわかりません。

RNアプリがバックグラウンドから再度開かれたかどうかを検出する適切な方法は何ですか? (理想的にはiOSサポート付き)

13
sAm_vdP

react-nativeによって提供されるAPIである AppState を確認する必要があります。

この例を確認してください。

import React, {Component} from 'react'
import {AppState, Text} from 'react-native'

class AppStateExample extends Component {

  state = {
    appState: AppState.currentState
  }

  componentDidMount() {
    AppState.addEventListener('change', this._handleAppStateChange);
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this._handleAppStateChange);
  }

  _handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
      console.log('App has come to the foreground!')
    }
    this.setState({appState: nextAppState});
  }

  render() {
    return (
      <Text>Current state is: {this.state.appState}</Text>
    );
  }

}
3
semirturgay

@semirturgayの答えは、アプリを離れることを検出する1つの方法です。 Androidの場合、ホームボタンまたは最近のアプリボタンのクリックを検出する方がはるかに優れています。これは、ソーシャルメディアや写真などの他のアプリからのアプリ内のフラグメントも背景状態をトリガーするためです。これは、カメラなどからプロファイルに写真を追加するアプリ内にあるため、望ましくありません。自宅を簡単に検出できます。そして最近のアプリボタンはAndroid with react-native-home-pressed 。このライブラリは単にAndroidボタンイベントを公開します。

最初にnpm i react-native-home-pressed --saveを使用してライブラリをインストールし、次にreact-native linkにリンクします。次に、アプリを再構築し、次のスニペットを追加します。

import { DeviceEventEmitter } from 'react-native'

class ExampleComponent extends Component {
  componentDidMount() {
    this.onHomeButtonPressSub = DeviceEventEmitter.addListener(
     'ON_HOME_BUTTON_PRESSED',
     () => {
       console.log('You tapped the home button!')
    })
    this.onRecentButtonPressSub = DeviceEventEmitter.addListener(
     'ON_RECENT_APP_BUTTON_PRESSED',
     () => {
       console.log('You tapped the recent app button!')
    })
  }
   componentWillUnmount(): void {
    if (this.onRecentButtonPressSub)   this.onRecentButtonPressSub.remove()
    if (this.onHomeButtonPressSub) this.onHomeButtonPressSub.remove()
  }
}
0
evanjmg