本篇博客原计划于一周前写完,因为过年偷懒了,今天补上。大家有什么疑问欢迎留言。
内容分为三部分,模块化,MVP,用注册功能代码实现。
第一部分模块化
简单讲解什么是模块化
- 相对独立业务拆分成“块”,单独进行开发调试
- 拼接业务模块,最后组装成App
为什么模块化
- 业务分离,解耦
- 通用化,代码复用
模块化图形示例
模块化.png如何实现模块化
- 公用模块抽取
- 业务模块抽取
- 主工程组装业务模块
模块之间通讯
- 跨模块跳转
- 跨模块接口调用
- ARouter路由框架实现
第二部分MVP架构
讲在最前,MVC,MVP,MVVM,都是一种思想,也不是一成不变的,没有好坏之分,根据项目不同,规模不同,选择适合自己项目的架构才是最好的选择。
MVP概念
mvp.jpg- View 试图层 一般是Activity,Fragment
- Presenter 通过试图回调把数据同步给视图层
- Model 业务层
MVP Google官方版介绍
MVP 优化版介绍
第三部分 以注册功能实现MVP架构与模块化
首先看一下已经建好的项目结构
项目结构.jpg当主工程依赖其他模块(比如模块1),但是模块1又需要单独开发调试时,可以动态对模块1进行设置,根据不同的设置,模块1可以分别以模块1运行,也可以以主工程的方式运行。
- 第一步 在gradle.properties 增加变量
#true表示是库工程,false表示主工程
isUserModule=false
- 第二步在相应模块的build.gradle(本问中对应的是用户模块的build.gradle)文件中进行动态判断。
if(isUserModule.toBoolean()){
apply plugin: 'com.android.library'
}else{
apply plugin: 'com.android.application'
}
动态加载AndroidManifest.xml文件,将sourceSets
部分放在android{}的最后就可以。文字不太清楚直接看下面代码。
#build.gradle 文件
if(isUserModule.toBoolean()){
apply plugin: 'com.android.library'
}else{
apply plugin: 'com.android.application'
}
...
android {
...
sourceSets {
main {
if (isUserModule.toBoolean()) {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
//release 模式下排除debug文件夹下的所有java文件
java {
exclude 'debug/**'
}
} else {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
}
}
}
}
dependencies {
...
}
sourceSets部分实现动态加载AndroidManifest.xml文件。
注册功能mvp结构图
mvp.pngMVP架构的实现
BaseActiviy
package com.gobagou.base.ui.activity
import android.support.v7.app.AppCompatActivity
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
open class BaseActivity : AppCompatActivity(){
}
BaseMvpActivity
package com.gobagou.base.ui.activity
import com.gobagou.base.presenter.BasePresenter
import com.gobagou.base.presenter.view.BaseView
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
open class BaseMvpActivity<T:BasePresenter<*>>:BaseActivity(), BaseView{
lateinit var mPresenter: T
override fun showLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hideLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onError() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
BasePresenter
package com.gobagou.base.presenter
import com.gobagou.base.presenter.view.BaseView
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
open class BasePresenter<T:BaseView> {
lateinit var mView: T
}
BaseView
package com.gobagou.base.presenter.view
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
interface BaseView {
fun showLoading()
fun hideLoading()
fun onError()
}
RegisterActivity
这个地方你可能会有疑问,做了这么多准备,为什么还要自己创建变量???
对,这么写其实是不科学的,后期做项目的时候,mPresenter,mPresenter.mView的实例化是不需要手动创建的,是采用dagger2来实现。dagger2像Rxjava2一样的神器。
package com.gobagou.user.ui.activity
import android.os.Bundle
import com.gobagou.base.ui.activity.BaseMvpActivity
import com.gobagou.user.R
import com.gobagou.user.presenter.RegisterPresenter
import com.gobagou.user.presenter.view.RegisterView
import kotlinx.android.synthetic.main.activity_register.*
import org.jetbrains.anko.toast
class RegisterActivity : BaseMvpActivity<RegisterPresenter>(), RegisterView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
mPresenter = RegisterPresenter()
mPresenter.mView = this
mRegisterBtn.setOnClickListener {
mPresenter.register("18910229999","123456")
}
}
override fun onRegisterResult(result: String) {
toast(result)
}
}
RegisterPresenter
在“业务逻辑”部分就是去请求网络等操作
package com.gobagou.user.presenter
import com.gobagou.base.presenter.BasePresenter
import com.gobagou.user.presenter.view.RegisterView
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
class RegisterPresenter: BasePresenter<RegisterView>() {
fun register(mobile:String, pwd:String){
/*
业务逻辑
*/
mView.onRegisterResult("注册成功")
}
}
RegisterView
回调视图,处理presenter放回的结果
package com.gobagou.user.presenter.view
import com.gobagou.base.presenter.view.BaseView
/**
* Author: Created by XHJ on 2019/2/9.
* 种一棵树最好的时间是十年前,其次是现在。
*/
interface RegisterView: BaseView {
fun onRegisterResult(result:String)
}
到这里,模块化与MVP架构就已经实现了。有兴趣的小伙伴也动手试一下吧。
Gitbub地址,如果对你有所帮助,给点个星,感谢。
Github地址:https://github.com/xiaohuangya123/MVPDemo
网友评论