ReactNative 本地资源文件

2017/08/02 ReactNative

iOS资源文件

RN项目目录结构图

RN项目目录结构图

iOS打包后app内部目录结构图

iOS打包后app内部目录结构图

从上两图可以看出来,iOS打包后,会把RN项目中(通过require)引用的资源文件(图片,html等文件)放到assets文件夹中。assets中的资源路径和RN项目中的是一样的。可以简单理解为ui-mobile改名为assets内部文件路径一样。

android资源文件

和iOS不同的是RN打包apk以后,会把资源整理到不同的drawable下,而不会放进assets文件夹里面。而drawable目录下只存放绘制文件(jpg、png、gif、xml等)所以,如果android项目中需要用到html,ttf等资源文件,还是需要手动加进android/app/src/main/assets路径下。

加载本地html问题

RN目录结构

// []代表文件夹

- [rn_project_name]
    - app.js
    - [htmls]
        - about.html
        - [imgs]
            - bg.png
    - [components]

about.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div style="alignment: center">
    <img src="./imgs/bg.png" width="100%" />
</div>
</body>
</html>

app.js

...
<WebView source={require('./htmls/about.html')}/>
...

现在我们需要用WebView组件加载并显示本地的about.html。在模拟器上,android和iOS都可以正常显示。但是,打包成apk和app以后,android会提示找不到about.html文件,而iOS可以打开about.html但找不到bg.png。其实这和RN打包资源文件方式有关(上面有提到)。

iOS解决方法

RN打包iOS的时候,会把(通过require)引用的资源文件打包到assets目录下,所以WebView可以正确找到about.html,而找不到bg.png

解决步骤:

  1. 在iOS目录下创建assets文件夹
  2. 按照RN目录结构在assets中加入缺失的文件/目录
  3. assets文件拖进Xcode中,并勾选 Create folder reference

iOS目录

Xcode Project

注意: 一定要勾选Create folder reference,成功以后在Xcode中显示蓝色的文件夹。

在Xcode中group是存放编译的文件,如:.m .h。(黄色文件夹) 而folder reference是不会编译的,会原封不动的打包进app里面。(蓝色文件夹)

android解决方法

上面已经提到,RN会把引用的文件打包进drawable目录下,因为html文件不是可绘制文件,所以会自动被删除。

解决步骤:

  1. 创建android/app/src/main/assets目录
  2. 把需要的文件放进assets
  3. RN中利用{ uri: 'file:///android_asset/***' }访问

androi 目录

app.js

...
<WebView source=/>
...

注意: assets文件夹会原封不动的保存在apk包中,不会被编译成二进制。

完美兼顾方法

普通方案

let source;
if (__DEV__) {
  source = require('./index.html');
} else {
  source = Platform.OS === 'ios' ? require('./htmls/about.html') : { uri: 'file:///android_asset/htmls/about.html' };
}

可传query方案:path/to/file.html?page=1&page_size=10

import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
let source;
const _source = resolveAssetSource(require('./index.html'));
if (__DEV__) {
  source = { uri: `${_source.uri}&id=${article.id}` };
} else {
  const sourceAndroid = { uri: `file:///android_asset/index.html?id=${article.id}` };
  const sourceIOS = { uri: `file://${_source.uri}?id=${article.id}` };
  source = Platform.OS === 'ios' ? sourceIOS : sourceAndroid;
}

引用:react native webview加载本地html资源文件的解决方案

Show Disqus Comments

Search

    Table of Contents