Axiu Blog
确实比内嵌html5页面顺畅太多了。下面撷取两个坑,证明一下,咱确实做过`rn`开发。 ### `iOS`图片不显示,`onLoad`等函数不执行 图片设置宽度占满整屏,高度按比例转换,用`top`属性,使图片垂直居中。 const \[imageHeight, setImageHeight\] = useState(0); function ima
项目需要客串开发`react-native`的应用。壳已经准备好,加`js`代码就行。虽然完全没有接触过APP开发的我有些手足无措,不过看到熟悉的生命周期和声明/调用方法,觉得这个活儿也能干。经过数天的“手册级”开发,最终成品看起来还不错,确实比内嵌html5页面顺畅太多了。下面撷取两个坑,证明一下,咱确实做过`rn`开发。 ### `iOS`图片不显示,`onLoad`等函数不执行 图片设置
项目需要客串开发`react-native`的应用。壳已经准备好,加`js`代码就行。虽然完全没有接触过APP开发的我有些手足无措,不过看到熟悉的生命周期和声明/调用方法,觉得这个活儿也能干。经过数天的“手册级”开发,最终成品看起来还不错,确实比内嵌html5页面顺畅太多了。下面撷取两个坑,证明一下,咱确实做过`rn`开发。 ### `iOS`图片不显示,`onLoad`等函数不执行 图片设置
React-Native两个图片展示问题
Max

项目需要客串开发react-native的应用。壳已经准备好,加js代码就行。虽然完全没有接触过APP开发的我有些手足无措,不过看到熟悉的生命周期和声明/调用方法,觉得这个活儿也能干。经过数天的“手册级”开发,最终成品看起来还不错,确实比内嵌html5页面顺畅太多了。下面撷取两个坑,证明一下,咱确实做过rn开发。

iOS图片不显示,onLoad等函数不执行

图片设置宽度占满整屏,高度按比例转换,用top属性,使图片垂直居中。

const [imageHeight, setImageHeight] = useState(0);

function imageLoad(value) { const {height, width} = value.nativeEvent.source; let tmpHeight = height / width * screenWidth; setImageHeight(tmpHeight); }

console.log('onLoadStart')} onLoadEnd={() => console.log('onLoadEnd')} resizeMode="contain" />

最终android上显示是这样

android-image-slide

iOS,emmm…..点完没反应,排查发现,onLoad/onLoadEnd等各种事件都没触发。

问题原因:如果给图片设置初始高度为0,在iOS下图片不会加载。如果设置为1,就正常,各种事件也会正常触发。

Android相册,图片一多就OOM导致app crash

如果要放置很多图片,又没有缩略图,全部加载就会报错(目测10几张,每张100k左右)

OOM(out of memory)即内存不足。有两类log表现:

09-23 11:43:04.829 27468 27692 I ReactNativeJS: 失败原因:Pool hard cap violation? Hard cap = 201326592 Used size = 194146848 Free size = 0 Request size = 12160512 09-23 11:43:04.829 27468 27692 I ReactNativeJS: 加载图片失败

I/ReactNativeJS( 8935): emit: [Function: emit] } I/SurfaceFlinger( 431): FPS: 39 W/Adreno-GSL( 8935): : sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory E/Adreno-GSL( 8935): : GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.

实际手机效果差不多,均无法显示x张以后的图片。

由于写习惯了web方式的js,会认为手机端渲染过程也是一样,图片占用固定大小,只要不是超级分辨率,都没问题。但是,android不是。

一个看起来正常的Image标签

在Android手机上的图片处理,大致是如下过程:

jpg/png -> 解码器 -> Bitmap -> 放入内存供使用

也就是说,都会以Bitmap存储到内存中。那么这个Bitmap会占用多大内存? 参考【 这里

以一张800 × 600分辨率的jpg,大小约135k的图片为例

Bitmap内存占用 ≈ 像素数据总大小 = 图片宽 × 图片高× (设备屏幕密度/资源目录对应dpi)^2 × 每个像素的字节大小

套用一下

17,280,000 = 800 × 600 × (480 / 160 )^2 × 4

即17M。

按照这个比例,大图片多来一些,APP OOM导致崩溃是指日可待的。

直观的解决办法,压缩图片。

幸好,react-native给出了一个resizeMethod的解决办法,https://facebook.github.io/react-native/docs/image.html#resizemethod

对于远大于(2倍及以上)实际显示大小尺寸的图片,需要用resizeMethod='resize'。其他情况使用'scale'

resizescale的区别在于,resize会存储一份更小的bitmap,所以占用的空间更小。resize过程要耗费一定的CPU。

scale则是通过canvas操作来使用硬件加速,bitmap大小不变。硬件加速会耗费GPU。

这一部分请参考fresco 关于resizing的文档

Comments