【附】相关架构及资料
源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,和技术大牛一起讨论交流解决问题。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
View 层通常是由一个 Activity(也可以是一个 Fragment,一个 View,这取决于 App 的结构),它包含了一个对 Presenter 的引用。理想情况下,Presenter 是通过依赖注入的方式提供的(比如 Dagger),但如果你没有使用这类工具,也可以直接创建一个 Presenter 对象。View 需要做的唯一一件事就是:当有用户操作发生时(比如一个按钮被点击了),就调用 Presenter 中的相应方法。
由于 View 必须与 Presenter 层无关,因此它就需要实现一个接口。下面是示例中使用到的接口:
interface LoginView {
fun showProgress()
fun hideProgress()
fun setUsernameError()
fun setPasswordError()
fun navigateToHome()
}
接口中有一些有效的方法来显示或隐藏进度条,显示错误信息,跳转到下一个页面等等。正如上面所提到的,有很多方式去实现这些功能,但我更喜欢罗列出最简单直观的方法。
然后,Activity 可以实现这些方法。这里我向你展示了一些用法,以便你对其用法有所了解:
class LoginActivity : AppCompatActivity(), LoginView {
…
override fun showProgress() {
progress.visibility = View.VISIBLE
}
override fun hideProgress() {
progress.visibility = View.GONE
}
override fun setUsernameError() {
username.error = getString(R.string.username_error)
}
}
但是如果你还记得,我还告诉过你,View 层使用 Presenter 来通知用户交互操作。下面就是它的用法:
class LoginActivity : AppCompatActivity(), LoginView {
private val presenter = LoginPresenter(this, LoginInteractor())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
button.setOnClickListener { validateCredentials() }
}
private fun validateCredentials() {
presenter.validateCredentials(username.text.toString(), password.text.toString())
}
override fun onDestroy() {
presenter.onDestroy()
super.onDestroy()
}
…
}
Presenter 被定义为 Activity 的属性,当点击按钮时,它会调用 validateCredentials()
方法,该方法将会通知 Presenter。
onDestroy()
方法亦是如此。我们稍后将会看到为什么在这种情况下需要通知 Presenter。
Presenter 层
Presenter 充当着 View 层和 Model 层的中间人。它从 Model 层获取收据并将格式化后数据返回给 View 层。
此外,与典型的 MVC 模式不同的是,Presenter 决定了当你在与 View 层交互时会做何响应。因此,它将为用户每个可执行的操作提供一种方法。我们在 View 层中看到了它,这里是代码实现:
class LoginPresenter(var loginView: LoginView?, val loginInteractor: LoginInteractor) :
LoginInteractor.OnLoginFinishedListener {
fun validateCredentials(username: String, password: String) {
loginView?.showProgress()
loginInteractor.login(username, password, this)
}
…
}
MVP 模式存在一些风险,常常被我们忽略的最重要的问题是 Presenter 永远依附在 View 上面。并且 View 层一般为 Activity,这就意味着:
- 我们可能会由于长时间的运行的任务而导致 Activity 的泄漏
- 我们可能会在 Activity 已经被销毁的情况下去更新视图
首先,倘若你能够保证能够在合理的时间内完成你的后台任务,我将不会过于担心。将你的 Activity 泄漏 5-10 秒会让你的 App 变得很糟糕,并且解决方案通常很复杂。
第二点反而更让人担心。想象一下,你花费 10 秒钟时间向服务器发送一个请求,但用户却在 5 秒钟后关闭了 Activity。当回调方法正在被调用并且 UI 被更新时,App 将会崩溃,因为 Activity 正在销毁中。
为了解决这个问题,我们可以在 Activity 中调用 onDestroy()
方法并清除 View:
fun onDestroy() {
loginView = null
}
这样我们就可以避免在任务结束时间与活动销毁时间不一致的情况下调用 Activity 了。
总结
在 Android 中将用户界面层与逻辑层分离并不简单,但 MVP 模式可以更加轻易地防止我们的 Activity 最终沦为高度耦合的、包含了成百上千行代码的类。在大型应用开发过程中,将代码管理好是很有必要的。否则,对代码的维护和扩展都会变得很困难。
如今,还有其他的代替方案比如 MVVM,我将会创作新的文章来对 MVVM 和 MVP 做比较,并帮助开发者迁移。所以请继续关注我的博客!
请记住 这个仓库,你可以在这查看 MVP 在 Kotlin 和 Java 中的代码示例。
如果你想要了解更多关于 Kotlin 方面的内容,可以查看我的 Kotlin for Android Developers 这本书 中的 sample 应用,或者观看 在线课程。
如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。
总结
学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!
最后如何才能让我们在面试中对答如流呢?
答案当然是平时在工作或者学习中多提升自身实力的啦,那如何才能正确的学习,有方向的学习呢?有没有免费资料可以借鉴?为此我整理了一份Android学习资料路线:
这里是一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套BAT大厂面试资料专题包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家。
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
最后,祝愿即将跳槽和已经开始求职的大家都能找到一份好的工作!
这些只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢再关注一下~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!