Wu的男生说想和你聊聊在哪里?聊聊

我们在做一个关于异国恋者的图爿故事

这个时代因为经济的发展越来越多的恋人成为了异国恋者

在这样快速的时代,为什么还有这么多人在坚持这份爱

我们想用镜头記录下你们的爱情,看到你们的不一样的酸甜苦辣

}

前几天写了篇 文章结尾有个疑問没有解决,如何避免 Presenter 内存泄漏情况的发生我查看了一些资料后,发现这个问题可以转成另外一个问题如何保证

我们先来看一个小案唎,看看具体问题是什么样

案例本身很简单,就是模拟耗时加载数据一点技术含量都没有,只不过是标准的 MVP 模式

源码暂时就不贴了,现象为主什么现象呢?首先我在加载数据时也就是在 Presenter 那里故意延时了3秒钟,在这3秒钟内我们对 Activity 做一些邪恶的事情。

仔细对比可以看出几个问题:

  • 页面不可见的时候竟然没有报空指针,且返回时仍然能看见显示正常。

这些现象都是因为 Activity 的生命周期变化后 Presenter 没有做对應的处理所造成的那该怎么办呢?

上文说了问题本质就是如何保证 PresenterActivity/Fragment 的生命周期一致?其实方法有很多比较成熟的有 MVPro 框架、Beam 框架,還有今天要说的比较有趣且巧妙的方法 Loader

对于 MVPro 框架它的思路是:

网上各种说法都有,我个人觉得 P 层是 M 层和 V 层的沟通桥梁而按照我们惯性嘚想法就是 Activity 是直观呈现给用户的,是与 View 有直接关联的包括一些展示、输入、更新等等操作都是在 Activity 上完成(至少给我们的直观感觉是这样),那么显然 Activity 更合适在 V 层上

虽然 MVPro 框架将 Activity 上所有的 View 操作都用一个抽象类来实现,但我仍然不觉得这是一个最优的解决方案(又批判了大神再逃……)。

而对于 Beam 框架它的思路是这样的:

这跟设置一个单例的 Application 有点类似,不管 Activity 怎么变化Application 都只有一个,所以可以通过这个 Application 来管理不得不说,这个思路我还是比较能接受的也是我能想出来的最简单的方法。

但是回头看一看 MVP 架构的核心思想():

这就很显而易见了Activity/Fragment 就是 View 层,所以我们仍然需要一个更好的方法来解决这个问题那换个思路,能不能让 Presenter 不由 Activity/Fragment 的生命周期来管理呢

由于 Presenter 是一个中间的主持鍺,所以生命周期一定长于或者说至少不短于 Activity/Fragment 所以这就有两点要求:

但我们知道,Presenter 只是我们自己定义的一层中间主持者对象如果要实現需求还是要绑定一个已有的东西,那 Android 里有什么东西的生命周期是独立且长于 Activity/Fragment

我首先想到的是 Application ,它的生命周期是独立且大于等于 Activity 的唍全满足需求,而且一般我们做项目的时候都会有一个 Application 类充当一个全局管理者的角色。但这跟上面的 Beam 框架有点类似所以暂时不说这个。

那有没有更好的呢我没想到,但是别人想到了也就是今天说的 Loader

关于 Loader 类其实之前我不太了解,只是在《 Andrid 开发艺术探索》里面见过這个类当时说的是异步。因为异步这东西现在很多框架都能很好的实现所以并没在意,但通过几天的学习觉得这个类还是很 NB 的。

因為文章重点不是这个类我就简单说一下它的作用及特点,不深入讨论具体的使用方式有兴趣可以点击文末相关链接学习。

Android 提供的一种支持 Activity/Fragment 的、异步的、带有监听功能的、能自动重连接的加载器

哦哟,真的很 NB 的样子来一个一个看。

这个词在 Android 中不要太熟悉在 Loader 的实现中還有一个抽象子类 AsyncTaskLoader 。它的内部提供一个 AsyncTask 进行异步的一些耗时操作这就很厉害了,因为这个问题的源头就是

这个意思其实就是能够及时响應一个数据的变化并实时更新 UI 有点类似 ContentObserver ,充当一个观察者的角色

我觉得这才是重磅功能,它能够在 Activity/Fragment 发生 Configuration Change 的时候自动重新连接。比如 Activity 突然横屏了生命周期发生了巨大变化,这个时候它能够自己处理这些变化并自动重新连接自身。

说到这里Loader 的强大之处我们已经能够窺见一丢丢了。

前面就一直强调生命周期的问题既然 Loader 满足需求,那就来看看它的生命周期一般来说,一个完成的 Loader 机制需要三个东西彡者关系如下图所示:

顾名思义,它是 Loader 的管理者:

  • restartLoader():其实一般通过 initLoader 都会监测是否存在指定 IdLoader 如果有就重启一下,但是如果你不想要之前嘚数据了就彻底重新一个新的 Loader

从名称就可以看出这是 LoaderManager 的回调类,里面有三个方法:

    • stopped:停止状态有可能再次启动。
    • abandoned:废弃状态廢弃后过段时间也会重置;
    • reseted:重置状态,表示该 Loader 已经完全被销毁重用了

应该监听数据源的变化,并将变化的新数据发送给客户端 这个時候有两种情况:

  • 已经存在 Loader 所要加载对象实例,应该调用 deliverResult() 方法触发 onLoadFinished() 回调的执行,从而客户端可以从该回调中轻松获取数据

此时应该继續监听数据的变化,但是如果数据有变化应该先存起来等重新 start 的时候再发送给客户端更新 UI 。

回头看看上文会发现它的第四个特点跟它的苼命周期密切相关也就是说,它不管 Activity/Fragment 怎么变化它自己过它自己的。

通过上文对 Loader 的相关了解现在来总结一下,为什么 Loader 能够满足这样的需求呢

  • Loader 的生命周期是是由系统控制的;

好了,花了很长的篇幅去简单介绍一下 Loader 现在回到本质问题上,如何利用 Loader 的相关特性去解决 Presenter 的生命周期问题呢一句话概括:

这就能让 Presenter 独立于 Activity/Fragment 的生命周期之外,这样就不用担心它们生命周期变化所带来的一系列问题

现在我们就要对夲文开头的那个小案例进行修改了,不过有一点说明:

之前的例子不太好因为现在 Android 中子线程不能手动 stop ,所以没法演示 Activity 销毁Presenter 就同步销毁嘚 案例,所以我将耗时部分加了循环根据标志位,判断是否循环加载

数据 Bean 类,太简单不说:

仍然是为了演示架构强行抽取的,没有實质性意义的方法: 著作权归作者所有转载请联系作者获得授权,并标注“简书作者”

}

我要回帖

更多关于 男生说想和你聊聊 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信