尊重版权,未经授权不得转载
本项目来自wcandillon 文章来自江清清的技术专栏(http://www.lcode.org)
原文地址(需要翻墙):https://hackernoon.com/image-caching-in-react-native-96d8df33ca84#.uaznyr11h
1.基本介绍
我最近正在开发一个React Native项目,同时想要给大家分享一个方法库,可以在图片显示的时候更加的平滑,以此来提升用户体验。该使用的库就是react-native-img-cache 项目实现的效果如下:
React Native交流10群:157867561,欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!
以上的动态效果中,会有头像,列表上面的图片等多种图片类型,在本项目中采用
2.用户上传的图片处理
针对用户自定义生成的图片(例如:app的用户上传的图片),我们有两种缓存策略:immmutable和mutable。immutable缓存策略用于图片地址不变的情况,反正mutable用于图片地址经常变化的情况。但是我们为什么同时需要这两种策略呢?让我们来看下面的用户配置项。
如上界面效果:当我们现实用于资料头像的时候,该图片通过后台服务器提供。然后当我们需要显示列表中的图像信息的时候,只需要显示用户头像的缩略图即可,并不需要发送额外的请求到服务器。
不可变的图片需要依靠后台服务器提供的最新图片的URL地址,在上面个人头像的案例中,后台可能会返回如下的信息:
1
2
3
4
5
6
7
8
9
|
{
profile: {
pictures: {
}
}
}
|
缓存这些头像图片是非常简单便捷的,通过图片URL地址的哈希串号,我们可以检测本地缓存文件中是否存在该图片,然后进行相关处理。下面就是采用react-native-fetch-blob库下载图片,然后进行缓存处理的实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import RNFetchBlob from
"react-native-fetch-blob"
;
const SHA1 = require(
"crypto-js/sha1"
);
export
default
class ImageCache {
static
function
get(uri: string): Promise<string> {
const path = RNFetchBlob.fs.dirs.CacheDir +
"_immutable_images/"
+ SHA1(uri) +
".jpg"
;
return
RNFetchBlob.fs.exists(path).then(exists => {
if
(exists) {
return
path;
}
else
{
return
RNFetchBlob.config({ path })
.fetch(
"GET"
, uri, {})
.then(() => path);
}
});
}
}
|
针对可变的图片,我们需要实现一个observable接口。针对APP应用中的每一个URL,该监听着会观察到在本地缓存中的图片当前的路径。如果图片被下载,那么该观察者就会收到图片的本地当前路径。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
type ImageCacheObserver = (path: string) => void;
interface IImageCacheObservable {
on(uri: string, observer: ImageCacheObserver);
dispose(observer: ImageCacheObserver);
}
interface IImageCache extends IImageCacheObservable {
/*
* When busting an URI, the new local path of the image will
* be provided to all its observers
*/
bust(uri: string);
}
|
下面的代码片段显示了如何在React Native组件实现IIMageCache的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
interface CachedImageProps {
uri: string;
style?: React.ImageStyle;
}
@observer
export class CachedImage extends Component<CachedImageProps, void> {
@observable private _path;
private handler = path =>
this
.path = path;
@computed get path() {
return
this
._path; }
set path(path: string) {
return
this
._path = path; }
observe(uri: string) {
// We start observing the cache
ImageCache.on(uri, handler):
}
componentWillMount() {
observe(
this
.props.uri);
}
componentWillReceiveProps(nextProps: CachedImageProps) {
observe(nextProps.uri);
}
componentWillUnmount() {
// We stop observing the cache
ImageCache.dispose(handler);
}
render() {
const {style} =
this
.props;
return
<Image style={style}
source={{ uri:
this
.store.path }}>{
this
.props.children}</Image>;
}
}
|
实现IImageCache接口类,可以实现同时不下载相同的图片。同时在接口方法中添加一个额外的immutable的参数来进行设置缓存策略。
1
2
3
4
5
|
interface IImageCacheObservable {
// The immutable parameter indicates which caching strategy to use
on(uri: string, observer: ImageCacheObserver, immutable: boolean);
dispose(observer: ImageCacheObserver);
}
|
针对具体的ImageCache的实现效果代码可以在react-native-img-cache库中找到
3.静态资源图片处理
针对静态图片资源,同时这边也提供一个小小的react-native-static-images库用来扫描应用的图片文件夹,然后生成包含应用中所有的静态图片资源的类。可以看如下一个实例:
1
2
3
4
5
6
7
8
|
/*
* Generated by https://github.com/wcandillon/react-native-static-images
*/
export
default
class Images {
static readonly resetPassword = require(
"../public/images/ResetPassword.jpg"
);
static readonly signIn = require(
"../public/images/SignIn.jpg"
);
static readonly signUp = require(
"../public/images/SignUp.jpg"
);
}
|
但是如果用户使用的是旧版本的应用,后台可能会引用到部分静态资源,但是这些图片没有在已安装的应用中。如果是这种情况,那我们就必须下载远程图片了,具体做法如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
export
default
class {
static getImage(id: string): any {
// We check if the image is present within the app bundle
const entry: any = _.get(Images, _.camelCase(id));
if
(entry !== undefined) {
return
entry;
}
else
{
// If not, we return a remote link for that image
return
{ uri: `${StaticDomain}/${id}` };
}
}
}
|
React Native交流10群:157867561,欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!
尊重原创,转载请注明:From Sky丶清(http://www.lcode.org) 侵权必究!