检查到更新后,点击下载,应用崩溃 〒_〒……



  • @tdzl2003 刚才我成功了一次!但继续发布更新版本就又崩溃了,还没理出头绪……
    之前崩溃是我冒昧修改了示例中的 doUpdate = info => {... ...}; 方法,因为那种直接使用箭头函数、语句式定义类方法的方式,在我的VSCode编辑器里提示语法错误,如图:

    0_1461925404036_doUpdate.png

    我改成了 doUpdate(info) {... ...} 方式,但就不行(是不是还需要.bind(this)一下呢?)!……可是改回来后,后续上传更新,就又更新不了……我再试试。

    另外,http://update.reactnative.cn/dashboard 这里的删除功能实在不好用,删了提示成功,一刷新,又回来了,也不知到底删掉没有哇~



  • @tdzl2003 测试了一晚上,我的操作步骤是:

    1. gradlew installRelease 一个基本包(手机同时安装);
    2. uploadApk到Update服务器;
    3. 修改Js代码,pushy bundle ……;
    4. 手机检查更新,能检测到新版本;
    5. 初始两三个版本还能更新;重复步骤3、4继续 pushy bundle 就不行了,开始闪退。有几次先卸载再重装,又可以更新了,但是;
    6. 到后来越来越不行……然后我开始有点崩溃……;
    7. 我觉得跟上面怀疑的改写 doUpdate = info => {... ...}; 形式似乎没关系,因为有成功的时候;
    8. 通过 update.reactnative.cn 网页界面的功能删除包实在不好用,删了没效果啊!
    9. 难道下载、更新这个环节还不稳定?当然我不知道别人是否有类似情况,不好说;
    10. @tdzl2003 @sunnylqm 还有什么黑魔法没有公布公布?


  • 经过一番再次测试,问题基本搞清

    以这里的 完整的示例 为例

    class MyProject extends Component {
      ... ...
      doUpdate = info => { ... ... };
      checkUpdate = () => { ... ... };
      ... ...
    }

    如果遵从示例写法的话,那么至少 doUpdate 这个箭头函数的写法要保持;
    如果像我觉得箭头函数写法和类内其它方法写法迥异不统一,那么要写成静态方法形式,像这样:

    class MyProject extends Component {
      ... ...
      static doUpdate(info) { ... ... };
      // 调用方式:MyProject.doUpdate(info);
      ... ...
    }

    或者把 doUpdate 方法提到类外,成为一个全局方法。这是为什么呢,吽?
    我的理解是:

    因为箭头函数的this绑定类不会绑定实例;作为实际执行热更新的方法,doUpdate 一定要“超然物外”,不能自己更新自己。
    试想,哪里有革自己命的道理?——想到这种逻辑,也就释然了

    @tdzl2003 对不对?有误导之处大家指出( ̄▽ ̄)"



  • @AndJoy 从理论上分析,案例中的doUpdate用不用箭头函数应该都没有关系,因为其中没有调用this。箭头函数只是为了保证在调用各种 this.xx方法时,this一定是指向当前的class的实例(不然就会报错,因为this在es6中默认值为空)
    static方法或者全局方法都没有实际区别(static和全局都访问不到this所代表的class的实例),还是那句话:案例中的doUpdate中并不涉及this的调用。倒也不需要“超然物外”,因为热更新并不在此时此刻革自己的命。它只是放一件新衣服在衣柜里,你下次出门的时候穿,而不是要你走在路上的时候就裸奔换衣服。

    你所遭遇的崩溃,很可能是在doUpdate中调用了this,却没有和案例一样使用箭头函数为doUpdate方法绑定this,同时由于报错终止了代码的执行,导致MarkSuccess没有调用,因而下次启动时自动回滚,导致更新不成功。



  • @sunnylqm 果然微妙啊,容我捋捋……



  • 仔细体会理解 @sunnylqm 的分析后,发现之前片面追求方法形式上的对等实现,而忽略了对更新流程的理解。

    其实崩溃问题出在checkUpdate里对doUpdate的调用时的this上,如果不通过箭头函数或手动绑定,那么运行状态下this是绑定到checkUpdate返回的promise对象上,这个对象本就没有doUpdate,所以调用会崩溃

    class MyProject extends Component {
      ... ...
      doUpdate = info => { ... ... };
      checkUpdate = () => {
        checkUpdate(appKey).then(...
        ... ...
          {text: '是', onPress: ()=>{this.doUpdate(info)}},
        ... ...
      };
      ... ...
    }

    所以无论是使用箭头函数还是手动绑定,要确保onPress: ()=>{this.doUpdate(info)}中的this是绑定到MyProject对象

    class MyProject extends Component {
      constructor() {
        this.checkUpdate = this.checkUpdate.bind(this);
      }
      doUpdate(info) { ... ... }
      checkUpdate() { ... ... }
    }

    我之前上面所说的使用静态方法、全局方法,虽然表面上凑巧避免了错误的绑定,但实际还是对这个更新流程没理解透



  • @AndJoy 所以你遭遇的崩溃其实发生在doUpdate之前。很多人会犯这样的错误,比如在renderRow中为onPress使用了箭头函数,但结果还是报this相关的错误,就不知道怎么回事了——》问题在于忘了给renderRow绑定this,从源头开始的this就错了——》好比虽然通往三楼的楼梯是对的,但通往二楼的楼梯却错了。



  • @sunnylqm 是啊……经过这么一番折腾,对于箭头函数、this绑定、异步调用、Class回调等ES6知识点,又深刻理解了许多!( ̄▽ ̄)"

    在《React/React Native 的ES5 ES6写法对照表》里的把方法作为回调提供部分有上面相关部分对比示例,原来看过但当时没感觉,这次算是切身体会了!



  • 也是用vscode,同样遇上了上述问题,感谢分享的解决过程!



  • @sherylynn 恭喜啦!……我这坑没白踩啊,呵呵( ̄▽ ̄)"