React Native的缓存和下载

一般我们有3种数据需要缓存下载:纯文本(比如API返回,状态标记等),图片缓存和其他静态文件。

纯文本

纯文本还是比较简单的,RN官方模块AsyncStorage就够了。它就跟HTML5里面的LocalStorage一样,你可以直接调setItem和getItem去操作数据,这两个方法都会返回一个promise。下面是官方的例子:
缓存数据

_storeData = async () => { try { await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.'); } catch (error) { // Error saving data } };

获取数据

_retrieveData = async () => { try { const value = await AsyncStorage.getItem('TASKS'); if (value !== null) { // We have data!! console.log(value); } } catch (error) { // Error retrieving data } };

在iOS上,AsyncStorage是native代码实现的,如果是小数据,就存在一个序列化字典里面,如果数据量太大,就单独存一个文件。在Android上,AsyncStorage使用的是RocksDB 或者 SQLite,取决于当前设备支持哪个。需要注意的是,Android上有大小限制,最大只能存6MB。这个是RN官方故意的,。如果需要的话,可以覆盖这个限制:

找到/android/app/src/main/java/MainApplication.java 并且导入 ReactDatabaseSupplier。

import com.facebook.react.modules.storage.ReactDatabaseSupplier;

导入后这个文件看起来像这样:

import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; import com.facebook.react.modules.storage.ReactDatabaseSupplier;

找到 onCreate 并设置新的 maximumSize,我这里设置为50MB

long size = 50L * 1024L * 1024L; // 50 MB ReactDatabaseSupplier.getInstance(getApplicationContext()).setMaximumSize(size);

改好后的onCreate看起来是这样:

@Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); long size = 50L * 1024L * 1024L; // 50 MB ReactDatabaseSupplier.getInstance(getApplicationContext()).setMaximumSize(size); }

虽然可以覆盖这个大小,但是不推荐这么做,这会让DB变得很大很丑,如果存储失败,虽然会抛错,但是数据并不会回滚,数据会更丑。如果你需要存储大的数据,你可以把它存为文件,我们后面会讲到

图片

如果一个图片我们已经加载过一次了,下次再用的时候我就不想再加载一次了,最好是直接能从缓存读出来。官方组件可以支持一些缓存,但是他只支持iOS。我这里找了两个比较流行的库react-native-cached-image 和 react-native-fast-image

react-native-cached-image

你可以跟着官方指引来安装,我就不多说了。但是要注意一点,这个库依赖 react-native-fetch-blob。这是一个native模块,在执行yarn add 或者 npm install后,你需要把它链接到你的项目,最简单的是执行react-native link react-native-fetch-blob自动链接。如果你的项目结构跟自动链接的不一样,你需要手动链接,可以参考这里。
这个库有三个比较有用的组件,CachedImage, ImageCacheProvider 和 ImageCacheManager,这是一个官方例子:

import React from 'react'; import { CachedImage, ImageCacheProvider } from 'react-native-cached-image'; const images = [ 'https://example.com/images/1.jpg', 'https://example.com/images/2.jpg', 'https://example.com/images/3.jpg', // ... ]; export default class Example extends React.Component { render() { return ( <ImageCacheProvider urlsToPreload={images} onPreloadComplete={() => console.log('hey there')}> <CachedImage source={{uri: images[0]}}/> <CachedImage source={{uri: images[1]}}/> <CachedImage source={{uri: images[2]}}/> </ImageCacheProvider> ); } }

ImageCacheManager是用来控制缓存的,你可以用它下载和删除图片,甚至你可以获取到下载图片的物理地址。它并没有缓存优先,强制刷新,强制使用缓存这种预设规则可以用,具体怎么用需要你自己定义。

react-native-fast-image

react-native-fast-image用起来更简单一点,在GitHub上的星星也多一点。这是一个native库,在iOS上是包装的 SDWebImage,Android上是包装的Glide (Android),这两个都是原生上万星星的库。因为是native库,所以安装后也需要链接,具体方法跟上面一样。这是一个使用例子:

import FastImage from 'react-native-fast-image' const YourImage = () => <FastImage style={styles.image} source={{ uri: 'https://unsplash.it/400/400?image=1', headers:{ Authorization: 'someAuthToken' }, priority: FastImage.priority.normal, cache: FastImage.cacheControl.web }} resizeMode={FastImage.resizeMode.contain} />

它预设了三种模式来控制缓存,其中一个是FastImage.cacheControl.web,这个策略就是网页是一样的了,他会采用HTTP的缓存控制头来控制,前端开发者应该很熟悉。这个库官方有很多例子可以看,看这里。做图片缓存的话,推荐用这个。

其他静态文件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwsgj.html