请教下 MVP 的 View 空指针问题

2019-11-26 11:27:02 +08:00
 kerb15

view 调用 presenter.do()方法

do 方法的实现如下:

do(){ view.showXXX(); }

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

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

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

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

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

view?.do()

Java:
if(view!=null)
{
view.do()
}
Mrxxy
2019-11-27 14:43:17 +08:00
有可能是内存泄漏导致,view 已经被销毁,但此时耗时操作才把结果返回,最常见网络请求,可以学下下官方 Lifecycle
lifewinner
2019-11-28 14:03:13 +08:00
我想问问为什么 view 会为空?导致 view 为空的原因是什么?
kerb15
2019-11-29 17:48:10 +08:00
@fansangg do 方法确实是用了 rxjava,然后 view.showxxx()方法是在 onSubscribe()中调用的,结果 monkey 测试报了 view 为空,确认过了 view.do()和 view.showxxx()是在同一个线程里面
kerb15
2019-11-29 17:48:31 +08:00
@lifewinner 不清楚,monkey 测试报的,所以我在猜测原因
kerb15
2019-11-29 17:49:13 +08:00
@starerlloll 这个确实是修复的办法,但我希望能够找到根因
kerb15
2019-11-29 17:50:35 +08:00
@fansangg [更正] do 方法确实是用了 rxjava,然后 view.showxxx()方法是在 onSubscribe()中调用的,结果 monkey 测试报了 view 为空,确认过了 presenter.do()和 view.showxxx()是在同一个线程里面
starerlloll
2019-11-29 18:22:08 +08:00
@kerb15 那就要看你的 view 是怎么传到到 presenter 的了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/623183

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX