V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kerb15
V2EX  ›  Android

请教下 MVP 的 View 空指针问题

  •  
  •   kerb15 · 2019-11-26 11:27:02 +08:00 · 10684 次点击
    这是一个创建于 1806 天前的主题,其中的信息可能已经有所发展或是发生改变。

    view 调用 presenter.do()方法

    do 方法的实现如下:

    do(){ view.showXXX(); }

    那么有没有可能在 view 在执行 presenter.do()方法的瞬间,View 挂了,导致 do 方法中,view 报了空指针错误?

    现在项目中跑 monkey 测试遇到了类似问题,有没有大佬帮忙解答一二?

    23 条回复    2019-12-03 01:56:21 +08:00
    pdog18
        1
    pdog18  
       2019-11-26 12:33:10 +08:00
    问题描述不完整,你的这个“瞬间”让人想象不出来,写代码不能靠玄学
    sankemao
        2
    sankemao  
       2019-11-26 14:19:01 +08:00 via iPhone   ❤️ 1
    动态代理 v 层方法,调用前判空
    Porster
        3
    Porster  
       2019-11-26 14:19:47 +08:00
    如果 do 不是同步执行的,那 view 可能会为 null。
    比如用 handler delay 300ms 执行 do()。Activity 关闭了,此时 view=null。
    KunMinX
        4
    KunMinX  
       2019-11-26 14:52:50 +08:00
    MVP 不能解决 生命周期安全问题,可以考虑通过 DataBinding + LiveData + ViewModel 规避这类问题。

    https://juejin.im/post/5dafc49b6fb9a04e17209922
    KunMinX
        5
    KunMinX  
       2019-11-26 14:55:19 +08:00
    补充,还包括解决 视图调用等 一致性问题,避免空指针隐患。
    boileryao
        6
    boileryao  
       2019-11-26 15:29:06 +08:00
    Jetpack
    kerb15
        7
    kerb15  
    OP
       2019-11-26 17:55:31 +08:00
    @pdog18 说是瞬间是因为,理论上,do 能够执行到,view 就是还在的,毕竟是 view 调用的,但是 view.showxxx 又报空指针了,那我能想到的就是,在 [presenter.do 这句代码执行] ,和 [view.showxxx 这句代码执行] 之间的时间片里面,发生了 view 挂了的情况
    kerb15
        8
    kerb15  
    OP
       2019-11-26 17:57:39 +08:00
    @KunMinX
    @boileryao
    是的,但是项目工程没有使用这种方式,而是传统的 mvp,所以只能妥协
    ryougifujino
        9
    ryougifujino  
       2019-11-27 09:02:06 +08:00
    MVP 最典型的 View 空指针情形是,请求网络接口的时候,在结果返回之前就结束了 Activity。这个时候 View 方法里调用控件就会报空指针。
    pdog18
        10
    pdog18  
       2019-11-27 09:27:04 +08:00
    @kerb15 我觉得你把问题复杂化了,就像前面哥们说的,只要是同步的话没可能会又这样的事(同步 + 互相强引用)。
    如果又这样的情况 Java 代码完全不能写了。
    fansangg
        11
    fansangg  
       2019-11-27 10:02:57 +08:00
    do 方法用 rxjava,view 挂了的话 dispose 掉,不就完事了
    fansangg
        12
    fansangg  
       2019-11-27 10:04:30 +08:00
    fun attachView(mRootView: V)

    fun detachView()
    starerlloll
        13
    starerlloll  
       2019-11-27 12:40:53 +08:00
    kotlin:

    view?.do()

    Java:
    if(view!=null)
    {
    view.do()
    }
    Mrxxy
        14
    Mrxxy  
       2019-11-27 14:43:17 +08:00
    有可能是内存泄漏导致,view 已经被销毁,但此时耗时操作才把结果返回,最常见网络请求,可以学下下官方 Lifecycle
    lifewinner
        15
    lifewinner  
       2019-11-28 14:03:13 +08:00 via Android
    我想问问为什么 view 会为空?导致 view 为空的原因是什么?
    kerb15
        16
    kerb15  
    OP
       2019-11-29 17:48:10 +08:00
    @fansangg do 方法确实是用了 rxjava,然后 view.showxxx()方法是在 onSubscribe()中调用的,结果 monkey 测试报了 view 为空,确认过了 view.do()和 view.showxxx()是在同一个线程里面
    kerb15
        17
    kerb15  
    OP
       2019-11-29 17:48:31 +08:00
    @lifewinner 不清楚,monkey 测试报的,所以我在猜测原因
    kerb15
        18
    kerb15  
    OP
       2019-11-29 17:49:13 +08:00
    @starerlloll 这个确实是修复的办法,但我希望能够找到根因
    kerb15
        19
    kerb15  
    OP
       2019-11-29 17:50:35 +08:00
    @fansangg [更正] do 方法确实是用了 rxjava,然后 view.showxxx()方法是在 onSubscribe()中调用的,结果 monkey 测试报了 view 为空,确认过了 presenter.do()和 view.showxxx()是在同一个线程里面
    starerlloll
        20
    starerlloll  
       2019-11-29 18:22:08 +08:00
    @kerb15 那就要看你的 view 是怎么传到到 presenter 的了
    kerb15
        21
    kerb15  
    OP
       2019-11-29 18:42:12 +08:00
    @starerlloll 初始化 presenter 时传过去,presenter 直接强引用。
    ukyoo
        22
    ukyoo  
       2019-12-02 11:55:59 +08:00
    在 Activity(View)销毁后, Presenter 的调用了 View 的方法,当然会报空指针了, MVP MVVM 都会遇到.
    MVP 要么加个方法,要么用 autodispose 之类的框架. MVVM 在 ViewModel#onCleared()里取消观察.
    fansangg
        23
    fansangg  
       2019-12-03 01:56:21 +08:00
    @kerb15 在 activity ondestory 的 dispose 掉,我在写 Presenter 的时候会在 base 里加上绑定 view 和解绑 view 的方法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3462 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:16 · PVG 08:16 · LAX 16:16 · JFK 19:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.