react-navigation 配置
react-navigation (使用的是5.x版本)需要配置linking,官网链接https://reactnavigation.org/docs/5.x/deep-linking/
import React, { Component } from "react";
import { Image, Platform, Linking } from "react-native";
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Home from "../screens/Home/index";
const prefix = Platform.OS == 'android' ? 'schemeapp://www.app.com/' : 'schemapp://www.app.com/';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
export default class Route extends Component {
render() {
const linking = {
prefixes: [prefix]
};
return (
<NavigationContainer
linking={linking}
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
>
<Stack.Navigator
mode="modal"
headerMode="float"
>
<Stack.Screen
name="Hhome"
component={Home}
options={{
title: '首页'
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
Android
先判断 是安卓还是ios,
如果是安卓环境,
监听APP是在后台,还是活跃的
先通过change监听,如果是活跃的,就调用跳转函数
跳转函数
通过Linking.getInitialURL()
获取外部跳转过来的url, 处理url 带过来的参数。
判断有没有登录
如果没有登录就跳转到登录页面,如果登录就跳转到首页。
import { StyleSheet, View, Linking, AppState, Platform, DeviceEventEmitter } from "react-native";
async componentDidMount() {
let self = this;
if(Platform.OS == "ios"){
// 要在 App 启动后也监听传入的 App 链接
// schemeapp://Home?routeName=Home
// schmeapp://www.app.com/Home?routeName=Home
this.linkingIOS()
} else {
AppState.addEventListener('change', this.onAppStateChange);
if (AppState.currentState === 'active') {
console.log('走了吗')
self.linking()
}
}
}
componentWillUnmount(){
Linking.removeEventListener('url', this._handleOpenURL);
AppState.removeEventListener('change', this.onAppStateChange)
}
// android scheme 监听
onAppStateChange = (nextAppState) => {
let self = this;
if (nextAppState === 'active') {
if(!self.state.activeFlag){
self.linking()
}
}
}
// android 跳转
linking(){
let self = this;
Linking.getInitialURL()
.then((url) => {
console.log('url',url)
self.setState({
activeFlag:true
},()=>{
if (url) {
let obj = self.handleUrl(url);
console.log('跳转',obj)
// self.getLogin(obj,url)
self.getISLogin(obj,url)
} else {
console.log('这个')
self.interval = setTimeout(() => {
self.props.navigation.replace("Login");
}, 2000);
}
})
})
}
// 取URL地址参数转为对象
handleUrl(url) {
const urlObj = {};
const middleStr = url.split('?');
const paramPairStr = middleStr[1]?middleStr[1].split('&'):[];
paramPairStr.forEach((element) => {
const singleParamStr = element.split('=');
urlObj[singleParamStr[0]] = singleParamStr[1];
});
console.log('参数',urlObj)
return urlObj;
}
// android 判断是否登录
getISLogin(param,url){
let self = this;
Storage.getString("token").then((token)=>{
console.log('token',token)
if(token){
console.log('param',param)
let routeName = param.routeName?param.routeName:'Home'
if(routeName=='Home'){
routeName = 'Home'
}
self.props.navigation.replace(routeName,param)
} else{
Toast.show('登录已过期,请重新登录!');
self.props.navigation.replace("Login");
}
})
}
IOS
如果是IOS 环境,调用linkingIOS
方法,
linkingIOS
先通过 Linking.getInitialURL()
获取 url, (测试大多数情况下是空的)
如果url不为空,就继续往后,判断登录;
如果url为空,就继续用另一种方法获取,用监听url获取,Linking.addEventListener('url', self._handleOpenURL)
如果监听到url,会调用_handleOpenURL方法,
_handleOpenURL方法
方法里面,获取到url,之后处理url带过啦的参数,再判断是否登录,如果登录了跳转到Home,如果没有登录就跳转到Login
// ios 跳转
linkingIOS(){
let self = this;
// Linking.getInitialURL():APP在运行当中,这个方法是不能处理APP被外部URL调起的情况的。
Linking.getInitialURL().then((url) => {
if (url) {
let obj = self.handleUrl(url);
console.log('跳转',obj)
self.getISLogin(obj,url)
} else{
Linking.addEventListener('url', self._handleOpenURL);
self.interval = setTimeout(() => {
self.props.navigation.replace("Login");
}, 2000);
}
}).catch(err => {
console.error('错误信息为:', err);
alert('错误信息为:' + err);
});
}
// ios
_handleOpenURL = (event) => {
//调用事件通知
console.log('监听了的url',event.url)
let obj = this.handleUrl(event.url);
this.getISLoginios(obj,event.url)
};
// ios 判断是否登录
getISLoginios(param,url){
let self = this;
Storage.getString("token").then((token) => {
console.log('tokenios',token)
if(token){
console.log('param',param)
let routeName = param.routeName?param.routeName:'Home'
if(routeName=='Home'){
routeName = 'Home'
}
self.props.navigation.push(routeName,param) // 需要使用push,防止 多次监听,重复跳转
} else {
Toast.show('登录已过期,请重新登录!');
self.props.navigation.push("Login");
}
})
}