foxhis-native-webview
v1.1.0
Published
高性能 React Native WebView 组件 - 自研原生实现,支持 Android 平台,提供完整的缓存控制、导航管理、JSBridge 等功能
Maintainers
Readme
foxhis-native-webview
高性能 React Native WebView 组件 - 自研原生实现
特性
- 原生性能 - 直接封装 Android WebView,零第三方依赖
- 缓存控制 - 4 种缓存模式,支持离线访问
- 导航管理 - 后退/前进/刷新/停止加载
- 加载反馈 - 进度回调、标题获取、错误处理
- JSBridge - 双向通信机制
- 拍照选图 - 内置相机拍照和相册选择功能
- 自定义相册 - 微信风格多选相册界面
- TypeScript - 完整类型定义
平台支持
| 平台 | 状态 | |------|------| | Android | ✅ 完全支持 | | iOS | 🚧 开发中 |
安装
npm install foxhis-native-webview
# 或
yarn add foxhis-native-webviewAndroid 配置
在 android/app/src/main/java/com/yourapp/MainApplication.java 中注册:
package com.yourapp;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactPackage;
import com.foxhis.webview.WebViewPackage; // 添加导入
public class MainApplication extends Application implements ReactApplication {
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new WebViewPackage() // 注册包
);
}
}或在 Kotlin 中:
package com.yourapp
import com.foxhis.webview.WebViewPackage // 添加导入
class MainApplication : Application(), ReactApplication {
override fun getPackages(): List<ReactPackage> {
return listOf(
MainReactPackage(),
WebViewPackage() // 注册包
)
}
}添加 Android 依赖
在 android/app/build.gradle 中添加:
dependencies {
// Glide - 用于自定义相册界面的图片加载
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
}添加权限
在 android/app/src/main/AndroidManifest.xml 中添加:
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<!-- 存储权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />快速开始
基础用法
import React, { useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import NativeWebView, { CacheMode, NativeWebViewRef } from 'foxhis-native-webview';
function WebViewScreen() {
const webViewRef = useRef<NativeWebViewRef>(null);
return (
<View style={styles.container}>
<NativeWebView
ref={webViewRef}
source={{ uri: 'https://example.com' }}
cacheMode={CacheMode.LOAD_DEFAULT}
onProgress={(progress) => console.log(`加载中: ${progress}%`)}
onLoadEnd={() => console.log('加载完成')}
onTitle={(title) => console.log('页面标题:', title)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
});加载 HTML 字符串
<NativeWebView
source={{
html: `
<!DOCTYPE html>
<html>
<body>
<h1>Hello, NativeWebView!</h1>
</body>
</html>
`
}}
cacheMode={CacheMode.LOAD_CACHE_ONLY}
/>导航控制
function NavigationControl() {
const webViewRef = useRef<NativeWebViewRef>(null);
return (
<View>
<Button title="后退" onPress={() => webViewRef.current?.goBack()} />
<Button title="前进" onPress={() => webViewRef.current?.goForward()} />
<Button title="刷新" onPress={() => webViewRef.current?.reload()} />
<Button title="停止" onPress={() => webViewRef.current?.stopLoading()} />
</View>
);
}缓存管理
import { WebViewCache } from 'foxhis-native-webview';
function CacheControl() {
const getCacheSize = async () => {
const size = await WebViewCache.getCacheSize();
console.log('缓存大小:', size); // "12.5 MB"
};
const clearCache = async () => {
const success = await WebViewCache.clearAllCache();
console.log(success ? '清理成功' : '清理失败');
};
return (
<View>
<Button title="查看缓存" onPress={getCacheSize} />
<Button title="清理缓存" onPress={clearCache} />
</View>
);
}JSBridge 通信
H5 发送消息到 RN:
// H5 页面代码
window.ReactNativeWebView.postMessage(JSON.stringify({
type: 'userLogin',
data: { userId: '123' }
}));RN 接收消息:
<NativeWebView
source={{ uri: 'https://example.com' }}
onMessage={(data) => {
const message = JSON.parse(data);
if (message.type === 'userLogin') {
console.log('用户登录:', message.data);
}
}}
/>RN 发送消息到 H5:
const webViewRef = useRef<NativeWebViewRef>(null);
const sendMessage = () => {
webViewRef.current?.postMessage(JSON.stringify({
type: 'updateTheme',
data: { theme: 'dark' }
}));
};拍照和相册功能
WebView 内置了完整的拍照和相册选择功能,H5 页面可以通过 JSBridge 直接调用。
H5 调用相机拍照:
// 打开相机(默认设置)
window.NativeWebView.openCamera();
// 打开相机(自定义参数)
window.NativeWebView.openCameraWithOptions(JSON.stringify({
maxWidth: 1920, // 图片最大宽度
quality: 85 // 图片质量 (1-100)
}));H5 调用相册选择:
// 相册单选(自定义微信风格界面)
window.NativeWebView.openGallerySingle();
// 相册多选(使用系统选择器)
window.NativeWebView.openGalleryMulti();
// 相册选择(自定义参数)
window.NativeWebView.openGalleryWithOptions(JSON.stringify({
maxCount: 9, // 最多选择数量
maxSizeKB: 2048, // 单张图片最大大小 (KB)
photosOnly: true // true: 只显示图片, false: 显示图片和视频
}));RN 接收选择的图片:
<NativeWebView
source={{ uri: 'https://example.com' }}
onMessage={(data) => {
const message = JSON.parse(data);
// 拍照或选择图片的回调
if (message.type === 'image_selected') {
console.log('图片来源:', message.source); // 'camera' | 'gallery'
console.log('图片列表:', message.images); // base64 或 uri 数组
}
}}
/>自定义相册特性:
- 📸 微信风格界面 - 4 列网格布局,圆形选择器
- 🔢 多选支持 - 最多可选择 9 张图片
- 🎬 视频支持 - 可选显示视频,带时长标识
- 📏 文件大小限制 - 支持设置最大文件大小
- 🌙 深色模式 - 自动适配系统主题
- 📱 序号显示 - 选中时显示选择序号
API 文档
NativeWebView Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| source | Source | 必填 | 加载源,支持 uri 或 html |
| cacheMode | CacheModeType | LOAD_DEFAULT | 缓存模式 |
| javaScriptEnabled | boolean | true | 是否启用 JavaScript |
| domStorageEnabled | boolean | true | 是否启用 DOM Storage |
| injectedJavaScript | string | - | 页面加载前注入的 JS 代码 |
| showsHorizontalScrollIndicator | boolean | true | 显示水平滚动条 |
| showsVerticalScrollIndicator | boolean | true | 显示垂直滚动条 |
| style | ViewStyle | - | 容器样式 |
事件回调
| 事件 | 参数 | 说明 |
|------|------|------|
| onProgress | (progress: number) => void | 加载进度(0-100) |
| onLoadEnd | () => void | 页面加载完成 |
| onError | (error: ErrorEvent) => void | 加载错误 |
| onTitle | (title: string) => void | 页面标题变化 |
| onNavigationStateChange | (state: NavigationState) => void | 导航状态变化 |
| onMessage | (data: string) => void | 收到 H5 消息 |
NativeWebViewRef 方法
| 方法 | 说明 |
|------|------|
| goBack() | 后退 |
| goForward() | 前进 |
| reload() | 刷新 |
| stopLoading() | 停止加载 |
| clearCache() | 清理缓存 |
| postMessage(message) | 发送消息到 H5 |
| injectJavaScript(script) | 执行 JavaScript |
缓存模式
import { CacheMode } from 'foxhis-native-webview';
CacheMode.LOAD_DEFAULT // 正常模式,优先网络
CacheMode.LOAD_CACHE_ELSE_NETWORK // 有缓存就用缓存,否则网络
CacheMode.LOAD_NO_CACHE // 只用网络
CacheMode.LOAD_CACHE_ONLY // 只用缓存(离线模式)迁移指南
如果你从项目内直接使用迁移到 npm 包:
之前(项目内)
import NativeWebView from './components/NativeWebView';
import { WebViewCache } from './utils/webviewCache';之后(npm 包)
import NativeWebView, { WebViewCache } from 'foxhis-native-webview';其他 API 完全一致,无需修改!
常见问题
1. Android 编译报错
确保在 MainApplication.java 中注册了 WebViewPackage。
2. 页面无法加载
检查 AndroidManifest.xml 是否添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />3. JSBridge 消息无法接收
确保 H5 页面正确调用 window.ReactNativeWebView.postMessage()。
开发计划
- [x] 拍照功能
- [x] 相册选择(自定义微信风格界面)
- [x] 多选图片和视频
- [ ] iOS 平台支持
- [ ] 自定义 UserAgent
- [ ] Cookie 管理
- [ ] 请求拦截
许可证
MIT License
贡献
欢迎提交 Issue 和 Pull Request!
作者: FOXHIS Team
