react-native之远程图片修改后APP不更新

知识就是力量,时间就是生命。这篇文章主要讲述react-native之远程图片修改后APP不更新相关的知识,希望能为你提供帮助。
今天在做客户的项目时,有一个需求是App上要显示远端的图片,而远端的图片有可能会更新,但图片名不变。
在react-native中,显示图片是用的自带的Image组件,大家都知道react在更新组件之前都会判断props或state是否有改变,当有改变时才会更新,否则不会刷新页面。
那问题就来了,远端的图片名不变,传入Image组件的props就不会变,Image组件就不会刷新,当远端的图片内容被修改之后,该怎么让前端同时显示最新的图片呢?
在遇到这个问题时,我是先在网上找到一个方法,说是两个同名的图片,如果内容不一样,则转成base64之后也不一样,可以以这种方式让前端刷新,
我当时也觉得这是一个好方法,于是我写了如下代码:

let  buffer  =  await  akita.get(‘/图片地址‘).buffer(); let  base64  =  ‘data:image/jpeg; base64,‘  +  buffer.toString(‘base64‘); render(){         ...         < Image  source={{uri:this.state.base64}}/>         ... }

结果真的可以更新了,我兴奋的打了一个release版放到真机上去测试,但没过两秒,app竟然闪退了,
瞬间感觉不会再爱了。
然后我开始输出日志查看,特别注明:不论是debug版还是release版,下面这条命令都能查看到输出日志,但.....具体情况还是你们自己试一下吧,反正不会爆炸。
adb  logcat  androidRuntime:E/

然后就输入了很多日志,全是关于java的,我都快哭了,最终,在日志里找到一个报错的输出:
  FATAL  EXCEPTION:  mqt_js Process:  com.appscreen,  PID:  28053 java.lang.RuntimeException:  Error  calling  function:  RCTDeviceEventEmitter:emit                 at  com.facebook.react.bridge.queue.NativeRunnable.run(Native  Method)                 at  android.os.Handler.handleCallback(Handler.java:733)                 at  android.os.Handler.dispatchMessage(Handler.java:95)                 at  com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)                 at  android.os.Looper.loop(Looper.java:136)                 at  com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:196)                 at  java.lang.Thread.run(Thread.java:841)   Caused  by:  java.lang.RuntimeException:  Failed  to  create  String  from  JSON:                 ...  7  more       Force  finishing  activity  com.appscreen/.MainActivity D/dalvikvm(28053):  GC_CONCURRENT  freed  484K,  12%  free  4735K/5344K,  paused  5ms+3ms,  total  50ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  31ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  42ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  12ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  14ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  35ms D/dalvikvm(28053):  WAIT_FOR_CONCURRENT_GC  blocked  27ms D/dalvikvm(28053):  GC_FOR_ALLOC  freed  173K,  9%  free  4985K/5452K,  paused  21ms,  total  22ms D/dalvikvm(  1014):  GC_FOR_ALLOC  freed  292K,  22%  free  7064K/9032K,  paused  65ms,  total  65ms I/Choreographer(28053):  Skipped  37  frames!    The  application  may  be  doing  too  much  work  on  its  main  thread. I/Process  (28053):  Sending  signal.  PID:  28053  SIG:  9 W/InputDispatcher(  1014):  channel  ‘41b9ec38  com.appscreen/com.appscreen.MainActivity  (server)‘  ~  Consumer  closed  input  channel  or  an  error  occurred.    events=0x9 E/InputDispatcher(  1014):  channel  ‘41b9ec38  com.appscreen/com.appscreen.MainActivity  (server)‘  ~  Channel  is  unrecoverably  broken  and  will  be  disposed! W/InputDispatcher(  1014):  Attempted  to  unregister  already  unregistered  input  channel  ‘41b9ec38  com.appscreen/com.appscreen.MainActivity  (server)‘ I/ActivityManager(  1014):  Process  com.appscreen  (pid  28053)  has  died. I/WindowState(  1014):  WIN  DEATH:  Window{41b9ec38  u0  com.appscreen/com.appscreen.MainActivity}   Caught  a  RuntimeException  from  the  binder  stub  implementation.   java.lang.NullPointerException             at  android.inputmethodservice.IInputMethodWrapper.setSessionEnabled(IInputMethodWrapper.java:280)             at  com.android.internal.view.IInputMethod$Stub.onTransact(IInputMethod.java:129)             at  android.os.Binder.execTransact(Binder.java:404)             at  dalvik.system.NativeStart.run(Native  Method)

看到这,我已经心凉了,这是什么错,完全和自己写的代码对不上号啊,
但是没办法,只能硬着头皮去网上扒拉,希望能找到答案,
结果是........让人很失望,我没有找到怎么解决这个bug。


后来实在感觉弄不出来了,只好去请教大神,对话如下:
我:大神,我这有个问题帮我看一下呗,
大神:  RN我也没搞过啊,
........我很心凉,这时大神又问了一句
大神: 你什么需求,
我: Q#$^#$& #@@& @(见文章开头),
大神:这还不好办,既然请求的是网络图片,你给图片地址后面加随机参数不就行了。
。。。。。。
好吧,大神就是大神,一句话让我网上扒拉资料的4个小时变成了一堆废渣。。
于是我就按大神说的来做,
randomString()  {     len  =  6;     var  $chars  =  ‘ABCDEFGHJKLMNPQRSTUVWXYZabcdefhijklmnprstuvwxyz0123456789‘;     var  maxPos  =  $chars.length;     var  pwd  =  ‘‘;     for  (let  i  =  0;   i  <   len;   i+=1)  {         pwd  +=  $chars.charAt(Math.floor(Math.random()  *  maxPos));     }     return  pwd; }render(){        let  imgUrl  =  SERVER_HOST  +  ‘/pic/‘  +  item.pic  +  ‘.jpg?code=‘  +  this.randomString();         ...         < Image  source={{uri:imgUrl}}/>         ... }



好吧,不得不再次感叹一声,大神就是大神,一句话让我之前写的代码全白费,又同时解决了我的问题。
在此,感谢大神。
---------------------------下面是重点----------------------------------------------
想让图片刷新,就必须保证传入 Image 组件的props是不一样的,基于文件名相同,则只能:
1,使用base64,不同图片内容的base64是不一样的,但这种方法可能会碰见我上面说的坑。
2,因为是网络图片,所以,每一个图片地址就像当于一个API接口,是可以带参数的。
        文件名后面跟上一些参数后,不管参数是什么,api接口没有变就能得到图片内容,同时,因为参数不一样,最终传入Image组件的props也不一样,这样就能让Image组件刷新了。

【react-native之远程图片修改后APP不更新】本文出自 “__无字书” 博客,请务必保留此出处http://wuzishu.blog.51cto.com/6826059/1967881

    推荐阅读