RN官方提供Linking库用于调起其他app或者本机应用。Linking的主要属性和方法有:
属性与方法 | 描述 |
---|---|
canOpenURL(url); | 判断设备上是否有已经安装相应应用或可以处理URL的程序,本方法会返回一个Promise 对象,只有一个回调参数,格式为Boolean值。 |
openURL(url); | 打开设备上的某个应用或可以处理URL的程序,本方法会返回一个Promise 对象。 |
addEventListener(type, handler); | 添加一个监听 Linking 变化的事件。type 参数应填'url' ,并提供一个处理函数。 |
removeEventListener(type, handler); | 删除一个事件处理函数。type 参数应填'url' 。 |
getInitialURL(); | 如果应用是被一个链接调起的,则会返回相应的链接地址。否则它会返回null 。 |
如调起微信为例,它们的使用核心代码如下:
// 在调起其他app或者本机应用前先检查是否已经安装:
Linking.canOpenURL('weixin://').then(supported => {
if (!supported) {
console.log('无法处理该URL:' + url);
} else {
return Linking.openURL('weixin://');
}
}).catch(err => console.error('错误:', err));
// 本应用被其注册过的外部url调起
Linking.getInitialURL().then(url => {
if (url) {
console.log('本app被其它应用调起:' + url);
}
}).catch(err => {
console.warn('错误:', err);
});
// 监听Linking的相关事件
Linking.addEventListener('url', this._handleOpenURL);
// 移除Linking的相关事件
Linking.removeEventListener('url', this._handleOpenURL);
_handleOpenURL(event) {
console.log(event.url);
}
利用URL Scheme调起其它应用
每一个App如果期望会与其它App发生联系,则都需要定义一个URL Scheme。如上段例子中的'weixin://'。它表示了应用允许被调起的唯一标识或者说链接。下面是一些常见App的URL Scheme:
// app应用
QQ: mqq://
微信: weixin://
新浪微博: weibo:// (sinaweibo://)
腾讯微博: tencentweibo://
淘宝: taobao://
支付宝: alipay://
美团: imeituan://
知乎: zhihu://
优酷: youku://
// 本机应用
电话:Linking.openURL(`tel:${'10086'}`);
浏览器:Linking.openURL('http://www.baidu.com');
短信:Linking.openURL('smsto:10086');
邮箱:Linking.openURL('mailto:10000@qq. com');
地图:Linking.openURL('geo:37.2122 , 12.222');
在Android中,直接使用openURL(url);函数即可调起其它App,前提是你需要知道相应App的url(即URL Scheme)是什么,一般来说是项目名称或应用名称。在IOS中,除此之外,还需要把URL Scheme加入到白名单中。详细方法可以参考这篇文章《ReactNative通过urlScheme打开其他app》。
现在,我创建了一个名称为auth的用户认证功能的RN项目。现在我们利用另一个项目来调起它,代码如下:
import React from 'react';
import { View, Button, Linking } from 'react-native';
class LinkingAPI extends React.Component {
_onPress = () => {
Linking.canOpenURL('auth://').then(canOpen=>{
if(canOpen){
Linking.openURL('auth://');
}
});
}
render(){
return(
<View>
<Button
title='Linking'
onPress={this._onPress}
/>
</View>
);
}
}
export default LinkingAPI;
效果:
结果显示auth已经被调起。这里要注意,auth项目需要有URL Scheme才允许被调起,那么如何配置URL Scheme呢?接着往下看。
自定义URL Scheme
android自定义URL Scheme:
以上面的auth项目为例,打开android/app/src/main/AndroidManifest.xml文件,配置如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.auth">
...
<application
...
android:launchMode="singleTask" // 配置1
...
<activity
...
// 配置2
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="auth" />
</intent-filter>
</activity>
...
</application>
</manifest>
ios自定义URL Scheme:
这个比较复杂,可以参考这篇文章《ReactNative注册自定义URL Scheme》
调起支付宝或微信支付
如果需要调起支付模块,也是可以的。我看别人已经有一些写得很好的文章了,都大同小异,相互补充,这里直接参考就好,就不赘言。
- https://blog.csdn.net/likeconan123/article/details/78999482
- https://blog.csdn.net/azhezzz/article/details/80841831
- http://fangzf.me/2017/12/05/react-native-%E9%9B%86%E6%88%90%E6%94%AF%E4%BB%98%E5%AE%9D/
- https://www.jianshu.com/p/0728c30820c3
- https://www.jianshu.com/p/7057fdab97ca
WebView
WebView可以理解为在应用中内置打开浏览器窗口,它主要有两个作用:
- 内置打开一个网站,一般放置在Modal组件中
- 与网站进行数据交互
如需交互,可添加onMessage函数监听,然后在webview 内部的网页中调用 window.postMessage 方法时可以触发此属性对应的函数,从而实现网页和 RN 之间的数据交换。网页端的 window.postMessage 只发送一个参数 data,此参数封装在 RN 端的 event 对象中,即 event.nativeEvent.data,data 只能是一个字符串。
关于通信详细可以参考这篇文章:《关于 React Native 与 WebView 的通信》
如在内置中打开爱奇艺,代码如下:
import React from 'react';
import { View, WebView, Button, Modal, Text } from 'react-native';
class WebViewComp extends React.Component {
constructor(props){
super(props);
this.state = {
modalVisible: false
};
}
_openModalWin = () => {
this.setState({modalVisible: true});
}
_closeModalWin = () => {
this.setState({modalVisible: false});
}
render() {
return (
<View style={{flex:1}}>
<Button title='打开页面' onPress={this._openModalWin}></Button>
<Modal
animationType='slide'
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => { this._closeModalWin(); }}
>
<WebView
style={{width:'100%',height:'100%'}}
source={{uri: 'https://www.iqiyi.com/'}}
automaticallyAdjustContentInsets={true} // 控制插入到导航栏,标签栏或者工具条之后的 web 内容是否自适应。默认为true
onLoad={() => {console.log('加载成功');}} // 当 WebView加载成功后执行的函数
onLoadEnd={() => {console.log('加载结束');}} // 当加载结束调用,不管是成功还是失败
onLoadStart={() => {console.log('开始加载');}} // 当 WebView刚开始加载时调用的函数
renderError={() => {console.log('视图渲染发生错误');}} // 返回一个视图用于显示错误
onMessage={() => {console.log('网页发送postMessage时触发');}} // 用于数据交互
startInLoadingState={true} // 与renderLoading配合使用,为true时表示允许自定义加载指示器
renderLoading={() => {
return <View><Text>这是自定义Loading...</Text></View>;
}}
/>
</Modal>
</View>
);
}
}
export default WebViewComp;
效果: