npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

foxhis-native-webview

v1.1.0

Published

高性能 React Native WebView 组件 - 自研原生实现,支持 Android 平台,提供完整的缓存控制、导航管理、JSBridge 等功能

Readme

foxhis-native-webview

高性能 React Native WebView 组件 - 自研原生实现

npm version License: MIT

特性

  • 原生性能 - 直接封装 Android WebView,零第三方依赖
  • 缓存控制 - 4 种缓存模式,支持离线访问
  • 导航管理 - 后退/前进/刷新/停止加载
  • 加载反馈 - 进度回调、标题获取、错误处理
  • JSBridge - 双向通信机制
  • 拍照选图 - 内置相机拍照和相册选择功能
  • 自定义相册 - 微信风格多选相册界面
  • TypeScript - 完整类型定义

平台支持

| 平台 | 状态 | |------|------| | Android | ✅ 完全支持 | | iOS | 🚧 开发中 |

安装

npm install foxhis-native-webview
# 或
yarn add foxhis-native-webview

Android 配置

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 | 必填 | 加载源,支持 urihtml | | 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