模板版本:v0.4.0
react-native-inappbrowser-reborn
本项目基于 react-native-inappbrowser-reborn 开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-inappbrowser-reborn。 版本所属关系如下:
| 三方库名称 | 三方库版本 | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | npm地址 |
|---|---|---|---|---|---|---|---|
| @react-native-ohos/react-native-inappbrowser-reborn | ~ 3.9.0 | Gitcode Releases | 0.82.* | 是 | API12+ | 3.7.0 | Npm Address |
| @react-native-ohos/react-native-inappbrowser-reborn | ~ 3.8.0 | Gitcode Releases | 0.77.* | 否 | API12+ | 3.7.0 | Npm Address |
| @react-native-ohos/react-native-inappbrowser-reborn | ~ 3.7.1 | Gitcode Releases | 0.72.* | 是 | API12+ | 3.7.0 | Npm Address |
| @react-native-oh-tpl/react-native-inappbrowser-reborn | <=3.7.0-0.0.4@deprecated | Github Releases(deprecated) | 0.72.* | 否 | API12+ | 3.7.0 | Npm Address |
1. 安装与使用
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/react-native-inappbrowser-reborn
yarn
yarn add @react-native-ohos/react-native-inappbrowser-reborn
下面的代码展示了这个库的基本使用场景:
使用时 import 的库名不变。
import React, {useState } from 'react';
import { StyleSheet, Text, Button ,ScrollView,View,StatusBarStyle,} from 'react-native';
import {InAppBrowser} from 'react-native-inappbrowser-reborn'
import {tryDeepLinking,openLink} from './utils'
export default function BrowserDemo() {
const [text, setText] = useState('');
const [url, setUrl] = useState('https://reactnative.dev');
const onOpenLink = async() => {
let resut = await openLink(url,{});
setText(JSON.stringify(resut))
}
const onTryDeepLinking = async() => {
let result = await tryDeepLinking();
setText(JSON.stringify(result))
return result;
}
const onIsAvailable = async () => {
let isAvailable = await InAppBrowser.isAvailable();
return isAvailable
}
const close =() => {
openLink(url, {});
setTimeout(function(){
console.info('-----------------')
InAppBrowser.close();
},10000)
}
const closeAuth =() => {
tryDeepLinking();
setTimeout(function(){
console.info('-----------------')
InAppBrowser.closeAuth();
},10000)
}
const warmup = () => {
InAppBrowser.warmup();
}
const mayLaunchUrl = () => {
InAppBrowser.mayLaunchUrl(url,[]);
}
return (
<View style={styles.container}>
<View style={styles.titleArea}>
<Text style = {styles.title}>BrowserDemo</Text>
</View>
<View style = {styles.inputArea}>
<Text style={styles.baseText}>
{text}
</Text>
</View>
<ScrollView style={styles.scrollView}>
<View style={ { flexDirection: 'column'}}>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>onOpenLink</Text>
<Button title='运行' color='#841584' onPress={onOpenLink}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>onTryDeepLinking</Text>
<Button title='运行' color='#841584' onPress={onTryDeepLinking}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>onIsAvailable</Text>
<Button title='运行' color='#841584' onPress={onIsAvailable}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>close</Text>
<Button title='运行' color='#841584' onPress={close}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>tryDeepLinking</Text>
<Button title='运行' color='#841584' onPress={tryDeepLinking}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>closeAuth</Text>
<Button title='运行' color='#841584' onPress={closeAuth}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>warmup</Text>
<Button title='运行' color='#841584' onPress={warmup}></Button>
</View>
<View style ={styles.baseArea}>
<Text style= {{flex:1}}>mayLaunchUrl</Text>
<Button title='运行' color='#841584' onPress={mayLaunchUrl}></Button>
</View>
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
flexDirection: 'column',
alignItems: 'center',
backgroundColor: '#F1F3F5',
},
baseText: {
fontWeight: 'bold',
textAlign:'center',
fontSize:16
},
titleArea:{
width:'90%',
height:'8%',
alignItems:'center',
flexDirection:'row',
},
title: {
width:'90%',
color:'#000000',
textAlign:'left',
fontSize: 30,
},
scrollView: {
width:'90%',
marginHorizontal: 20,
},
inputArea: {
width:'90%',
height:'10%',
borderWidth:2,
borderColor:'#000000',
marginTop:8,
justifyContent:'center',
alignItems:'center',
},
baseArea: {
width:'100%',
height:60,
borderRadius:4,
borderColor:'#000000',
marginTop:8,
backgroundColor:'#FFFFFF',
flexDirection: 'row',
alignItems:'center',
paddingLeft:8,
paddingRight:8
}
});
新建utils.ts文件:
import {Alert,Platform,} from 'react-native';
import {InAppBrowser} from 'react-native-inappbrowser-reborn'
export interface options {
dismissButtonStyle?: 'done' | 'close' | 'cancel',
preferredBarTintColor?:string,
preferredControlTintColor?:string
}
export const openLink = async (
url: string,
statusBarStyle: options,
animated = true,
) => {
let result = await InAppBrowser.open(
url,
{
dismissButtonStyle:statusBarStyle.dismissButtonStyle,
preferredBarTintColor:statusBarStyle.preferredBarTintColor,
preferredControlTintColor:statusBarStyle.preferredControlTintColor
}
);
Alert.alert('Response', JSON.stringify(result));
return result;
}
export const getDeepLink = (path = '') => {
const scheme = 'my-demo';
const prefix =
Platform.OS === 'android' ? `${scheme}://demo/` : `${scheme}://`;
return prefix + path;
};
export const tryDeepLinking = async () => {
const loginUrl = 'https://proyecto26.github.io/react-native-inappbrowser/';
const redirectUrl = getDeepLink();
const url = `${loginUrl}?redirect_url=${encodeURIComponent(redirectUrl)}`;
try {
if (await InAppBrowser.isAvailable()) {
const result = await InAppBrowser.openAuth(url, redirectUrl, {
// iOS Properties
ephemeralWebSession: false,
});
//await sleep(800);
return result
} else {
return 'InAppBrowser is not supported :/'
}
} catch (error) {
console.error(error);
}
return 'Something’s wrong with the app'
};
2. Link
| 是否支持autolink | RN框架版本 | |
|---|---|---|
| ~3.9.0 | Yes | 0.82 |
| ~3.8.0 | No | 0.77 |
| ~3.7.1 | Yes | 0.72 |
| <= 3.7.0-0.0.4@deprecated | No | 0.72 |
使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。
ManualLink: 此步骤为手动配置原生依赖项的指导
首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony。
2.1. Overrides RN SDK
为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。
关于该字段的作用请阅读官方说明
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}
2.2. 引入原生端代码
目前有两种方法:
- 通过 har 包引入;
- 直接链接源码。
方法一:通过 har 包引入(推荐)
har 包位于三方库安装路径的 `harmony` 文件夹下。
打开 entry/oh-package.json5,添加以下依赖
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@react-native-ohos/react-native-inappbrowser-reborn": "file:../../node_modules/@react-native-ohos/react-native-inappbrowser-reborn/harmony/inappbrowser.har"
}
点击右上角的 sync 按钮
或者在命令行终端执行:
cd entry
ohpm install
方法二:直接链接源码
如需使用直接链接源码,请参考[直接链接源码说明](./link-source-code.md)
2.3. 配置 CMakeLists 和引入 InappbrowserRebornPackage
打开 entry/src/main/cpp/CMakeLists.txt,添加:
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
# RNOH_BEGIN: manual_package_linking_1
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-inappbrowser-reborn/src/main/cpp" ./inappbrowser-reborn)
# RNOH_END: manual_package_linking_1
# RNOH_BEGIN: manual_package_linking_2
+ target_link_libraries(rnoh_app PUBLIC rnoh_inappbrowser_reborn)
# RNOH_END: manual_package_linking_2
打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
+ #include "InappbrowserRebornPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<RNOHGeneratedPackage>(ctx),
+ std::make_shared<InappbrowserRebornPackage>(ctx)
};
}
2.4. 在 ArkTs 侧引入 RNInAppBrowserPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
...
+ import { RNInAppBrowserPackage } from '@react-native-ohos/react-native-inappbrowser-reborn/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
+ new RNInAppBrowserPackage(ctx),
];
}
2.5. 必要的配置项
该模块的内容无法通过autolink自动生成,始终需要手动配置。
2.5.1. 配置Entry(该模块始终需要手动配置)
1.在 entry/src/main/ets/entryability 下创建 BrowserManagerAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
export default class BrowserManagerAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/BrowserManagerPage', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
2.在 entry/src/main/module.json5注册BrowserManagerAbility
"abilities":[{
"name": "BrowserManagerAbility",
"srcEntry": "./ets/entryability/BrowserManagerAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"visible": true,
}
...
]
3.在 entry/src/main/ets/pages 下创建 BrowserManagerPage.ets
import { BrowserPage } from '@react-native-ohos/react-native-inappbrowser-reborn/Index'
@Entry
@Component
struct ChromeTabsManagerPage {
build() {
Row(){
Column(){
BrowserPage();
}
.width('100%')
}
.height('100%')
}
}
4.在 entry/src/main/resources/base/profile/main_pages.json 添加配置
{
"src": [
"pages/Index",
"pages/BrowserManagerPage"
]
}
5.如果需要预热应用内浏览器客户端,使其启动速度显著加快,可以将以下内容添加到BrowserManagerAbility
import { RNInAppBrowserModule } from '@react-native-ohos/react-native-inappbrowser-reborn/ts';
export default class BrowserManagerAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
RNInAppBrowserModule.start();
}
}
2.6. 运行
点击右上角的 sync 按钮
或者在命令行终端执行:
cd entry
ohpm install
然后编译、运行即可。
3. 约束与限制
3.1. 兼容性
本文档内容基于以下版本验证通过:
- RNOH: 0.72.96; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
- RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71;
- RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
- RNOH: 0.82.1; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
4. 属性
"Platform"列表示该属性在原三方库上支持的平台。
"HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
iOS Options
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| dismissButtonStyle | 关闭按钮的样式。[done/close/cancel] | String | no | iOS | yes |
| preferredBarTintColor | 用于导航栏和工具栏背景的着色颜色。[white/#FFFFFF] | String | no | iOS | yes |
| preferredControlTintColor | 用于导航栏和工具栏上控制按钮的着色颜色。[gray/#808080] | String | no | iOS | yes |
| readerMode | 指定 Safari 是否应进入阅读模式(如果可用)的值。[true/false] | Boolean | no | iOS | no |
| animated | 是否对呈现进行动画处理。[true/false] | Boolean | no | iOS | no |
| modalPresentationStyle | 模态呈现视图控制器的呈现样式。[automatic/none/fullScreen/pageSheet/formSheet/currentContext/custom/overFullScreen/overCurrentContext/popover] | String | no | iOS | no |
| modalTransitionStyle | 呈现视图控制器时使用的过渡样式。[coverVertical/flipHorizontal/crossDissolve/partialCurl] | String | no | IOS | no |
| modalEnabled | 以模态方式呈现 SafariViewController 或改为推送方式。[true/false] | Boolean | no | iOS | no |
| enableBarCollapsing | 确定浏览器的工具栏是否折叠。[true/false] | Boolean | no | iOS | no |
| ephemeralWebSession | 防止重用前一个会话的 cookie(仅限 openAuth)。[true/false] | Boolean | no | iOS | no |
| formSheetPreferredContentSize | iPad formSheet 模态框的自定义尺寸。[{width: 400, height: 500}] | Boolean | no | iOS | no |
Android Options
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| showTitle | 设置是否在自定义标签页中显示标题。[true/false] | Boolean | no | Android | no |
| toolbarColor | 设置工具栏颜色。[gray/#808080] | String | no | Android | no |
| secondaryToolbarColor | 设置辅助工具栏的颜色。[white/#FFFFFF] | String | no | Android | no |
| navigationBarColor | 设置导航栏颜色。[gray/#808080] | String | no | Android | no |
| navigationBarDividerColor | 设置导航栏分隔线颜色。[white/#FFFFFF] | String | no | Android | no |
| enableUrlBarHiding | 启用当用户向下滚动页面时隐藏 URL 栏。[true/false] | String | no | Android | no |
| enableDefaultShare | 在菜单中添加默认分享项。[true/false] | String | no | Android | no |
| animations | 设置启动和退出动画。[{ startEnter, startExit, endEnter, endExit }] | Object | no | Android | no |
| headers | 数据为键值对,将作为 HTTP 请求头发送到提供的 URL。[{ 'Authorization': 'Bearer ...' }] | Object | no | Android | no |
| forceCloseOnRedirection | 在新任务中打开自定义标签页,以避免重定向回应用 scheme 时出现问题。[true/false] | Boolean | no | Android | no |
| hasBackButton | 设置返回箭头而不是默认的 X 图标来关闭自定义标签页。[true/false] | Boolean | no | Android | no |
| browserPackage | 用于处理自定义标签页的浏览器包名。 | Boolean | no | Android | no |
| showInRecents | 确定浏览的网站是否应显示为 Android 最近任务/多任务视图中的单独条目。[true/false] | Boolean | no | Android | no |
| includeReferrer | 确定是否将您的包名作为引荐来源包含在内以供网站跟踪。[true/false] | Boolean | no | Android | no |
5. API
"Platform"列表示该属性在原三方库上支持的平台。
"HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| Name | Description | Type | Required | Platform | HarmonyOS Support |
|---|---|---|---|---|---|
| open | 打开应用内浏览器。 | function | no | iOS/Android | yes |
| close | 关闭当前呈现的浏览器。 | function | no | iOS/Android | yes |
| openAuth | 打开身份验证会话。 | function | no | iOS/Android | yes |
| closeAuth | 关闭当前的身份验证会话。 | function | no | iOS/Android | yes |
| isAvailable | 检测设备是否支持此功能。 | function | no | iOS/Android | yes |
| onStart | 用于预热浏览器以加快导航速度,并指示给定的 URL 可能会在将来加载,HarmonyOS中 为 start,功能一致。 | function | no | Android | yes |
| warmup | 预热浏览器进程。 | function | no | Android | yes |
| mayLaunchUrl | 预加载可能导航的 URL。 | function | no | Android | yes |
6. 遗留问题
7. 其他
8. 开源协议
本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。