当应用程序处于后台状态时,如何清除间隔



我有一个组件,它每隔30秒就会提取一个请求,它运行正常。但我希望当应用程序进入后台状态时,请求会停止,当应用程序处于前台时,请求就会启动,反之亦然。有什么解决办法吗。

这是我的组件文件。

Notifications.js

/**
 * Notification Button
 */
import React from "react";
import { View, TouchableWithoutFeedback, Text } from "react-native";
import { connect } from "react-redux";
import Icon from 'react-native-vector-icons/MaterialIcons';
// styles
import styles from "./Styles";
// global styles
import globalStyles from "BkProvider/src/styles/global";
import { colors } from "BkProvider/src/styles/base";
// root navigator
import { rootNavigator } from "BkProvider/src/screens/DashboardGroup";
// strings
import strings from "BkProvider/src/strings";
// actions
import { getSystemAlerts, seeAllSystemAlertLogs, stopNotificationTick } from "BkProvider/src/actions";
// Navigation constants
import NavigationConstants from "BkProvider/src/constants/NavigationConstants";
const { posRelative } = globalStyles;
class NotificationButton extends React.Component {
    componentDidMount() {
        this.props.getSystemAlerts();
    }
    componentWillUnmount() {
        stopNotificationTick();
    }
    /**
     * Function to open system alerts popup
     */
    openSystemAlerts() {
        this.props.seeAllSystemAlertLogs(this.props.unseenAlertLogIdsArray);
        rootNavigator.push({
            screen: NavigationConstants.SYSTEM_ALERTS_LISTING,
            title: strings.allNotifications,
            backButtonTitle: ''
        });
    }
    render() {
        const { unseenAlertLogIdsArray } = this.props;
        return (
            <TouchableWithoutFeedback onPress={this.openSystemAlerts.bind(this)}>
                <View style={styles.button}>
                    <View style={[posRelative]}>
                        <Icon
                            name="notifications-none"
                            size={27}
                            color={colors.white}
                        />
                        {(unseenAlertLogIdsArray && unseenAlertLogIdsArray.length > 0) &&
                            <Text style={styles.badge}>{unseenAlertLogIdsArray.length}</Text>
                        }
                    </View>
                </View>
            </TouchableWithoutFeedback>
        );
    }
}
const mapStateToProps = ({ systemAlerts }) => {
    const { unseenAlertLogIdsArray } = systemAlerts;
    return { unseenAlertLogIdsArray }
}
export default connect(mapStateToProps, {
    getSystemAlerts,
    seeAllSystemAlertLogs
})(NotificationButton);

Actions.js

/**
 * System Alerts Actions
 */
import Toast from "react-native-simple-toast";
import { NetInfo } from "react-native";
// action types
import {
    GET_SYSTEM_ALERTS,
    SEE_ALL_SYSTEM_ALERT_LOGS
} from "BkProvider/src/actions/actionTypes";
// helpers methods
import { getUserId } from "./AppInitializer";
// webservice config
import WebServiceConfig, { APITypes } from "../webservice/WebServiceConfig";
import WebService from "../webservice/WebService";
import APINames from "../webservice/APINames";
let timer = null;
let globalDispatch;
let webServiceObject
/**
 * Function To Get System Alerts
 */
export const getSystemAlerts = () => (dispatch) => {
    clearInterval(timer);
    globalDispatch = dispatch;
    let apiConfig = new WebServiceConfig(APINames.LoadSystemAlertLogs),
        httpParams = {
            'page': "",
            'limit': "",
            'role': 'provider',
            'uid': getUserId()
        }
    webServiceObject = new WebService(onResultCallback)
        .addPostParameterObject(httpParams)
        .addServiceConfiguration(apiConfig)
    timer = setInterval(() => notificationsTick(), 15000);
    notificationsTick();
}
/**
 * API Response Callback Handler
 */
const onResultCallback = (webServiceResultObj) => {
    if (webServiceResultObj.isSuccess && webServiceResultObj.response != null) {
        if (webServiceResultObj.response.api_status === 1) {
            if (globalDispatch) {
                globalDispatch({ type: GET_SYSTEM_ALERTS, payload: webServiceResultObj.response.data });
            }
        }
    } else {
        if (webServiceResultObj.shouldShowErrorMessage)
            Toast.show(webServiceResultObj.errorMessage)
    }
}
/**
 * System Alerts Notification Ticks
 */
const notificationsTick = () => {
    NetInfo.isConnected.fetch().then(isConnected => {
        if (isConnected) {
            if (webServiceObject)
                webServiceObject.execute();
        }
    })
}
/**
 * Function To Clear The Interval Of System Alerts Api
 */
export const stopNotificationTick = () => {
    clearInterval(timer);
}
/**
 * Function To See All System Alerts Logs
 */
export const seeAllSystemAlertLogs = (unseenAlertLogIdsArray) => (dispatch) => {
    if (unseenAlertLogIdsArray) {
        let apiConfig = new WebServiceConfig(APINames.SeeAllSystemAlertLogs)
            .setAPIType(APITypes.POST);
        // params
        let params = {
            role: "provider",
            uid: getUserId(),
            unseen_log_ids: unseenAlertLogIdsArray
        }
        dispatch({ type: SEE_ALL_SYSTEM_ALERT_LOGS }); // dispatch an action to see all system alert logs
        new WebService()
            .addPostParameterObject(JSON.stringify(params))
            .addServiceConfiguration(apiConfig)
            .execute()
    }
}

只需在调用notificationsTick时检查AppState即可。

if(AppState.currentState === "active"){
    notificationsTick(); 
}

请注意,当你的应用程序处于后台时,JS计时器可能不会被调用-根据我自己的经验,在iOS上,单击主页按钮,触摸电源按钮进入睡眠模式,应用程序Javascript在10秒内被冻结。当你的应用程序回到前台时,他们可能会被呼叫。。。你应该测试

一个更健壮的实现将在计时器上保留一个引用,并在应用程序进入后台时取消它。

在这种情况下,您应该使用应用程序状态,这是我使用的示例代码

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>
    );
  }
}

有一个React原生API。https://facebook.github.io/react-native/docs/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>
    );
  }
}

此控制台记录应用程序的当前状态,因此您需要将此AppState添加到您的状态并执行所需操作。

最新更新