前言
因为 MVP、MVVM、组件化架构的衰亡,MVC 架构在 android 中的利用变得越来越少,但 MVC 是根底,了解好 MVC 能力更好的了解 MVP,MVVM,因为后两种都是基于 MVC 倒退而来的。
有些人认为只有架构好 App 就做得好,这种意识其实是谬误的,架构的实质肯定是服务于业务的。每一种架构肯定有它的长处和毛病,能适宜本人的需要、进步开发效率的架构就是一个好的架构。
例如一个性能绝对比较简单并且前期也不再扩大的 App,齐全能够用 MVC 架构来写,将逻辑全副写在 Activity 或者 Fragment 里,如果你用 MVP 这种架构,相应的你就要减少很多类,可能并不能进步你的开发效率。
Android 中 MVC 模式角色阐明
在 Android 中我的项目中,MVC 中的 View 就是咱们的 XML,而逻辑就是咱们的 Activity 或者 Fragment 等类,他们的分工是明确的,布局就负责 UI,Activity 就负责逻辑,Model 负责数据的解决。
类型 | 定义 | 表现形式 |
---|---|---|
M(Model) | 模型层 (数据存储、逻辑解决) | Model 类 |
V(View) | 视图层 (UI 展现) | 布局文件、Activity |
C(Controller) | 管制层 (逻辑解决) | Activity |
MVC 实例解说
我置信 MVC 架构大家都晓得,实践局部我就不讲那么多了,咱们通过一个实例来解说 MVC 架构的具体实现。
这个实例的整体性能非常简单,就是利用 Okhttp 申请一个 url,而后利用 Gson 解析数据,Glide 显示图片,RecyclerView 显示列表,实例成果如下所示,这里我应用的 API 是从干货集中营 上找的,API 是:https://gank.io/api/v2/data/c…
创立实体类
通过接口返回的 Json 数据,咱们就能够创立实体类了,咱们能够手动写,也能够用工具间接生成,如果是用 Java 语言,我举荐用 GsonFormat,如果是用 Kotlin 语言,就用 JsonToKotlinClass 插件来主动生成,因为我是用 Kotlin 语言来写的,所以我就用 JsonToKotlinClass 来主动生成实体类代码,如下所示:
data class DataBean(
val data: List<Data>,
val page: Int,
val page_count: Int,
val status: Int,
val total_counts: Int
)
data class Data(
val _id: String,
val author: String,
val category: String,
val createdAt: String,
val desc: String,
val images: List<String>,
val likeCounts: Int,
val publishedAt: String,
val stars: Int,
val title: String,
val type: String,
val url: String,
val views: Int
)
创立 View 层
视图层就是咱们的布局文件,代码很简略,就是一个全屏的 RecyclerView,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
因为咱们这里用了 RecyclerView,所以咱们得创立一个 RecyclerView 的适配器,代码如下所示:
class MvcRecyclerAdapter(private val dataList: List<Data>, private val context: Context) : RecyclerView.Adapter<MvcRecyclerAdapter.ViewHolder>() {inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {val ivImg: ImageView = view.findViewById(R.id.iv_img)
val tvDesc: TextView = view.findViewById(R.id.tv_desc)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_list_item, parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) {val bean = dataList[position]
Glide.with(context).load(bean.images[0]).into(holder.ivImg)
holder.tvDesc.text = bean.desc
}
override fun getItemCount() = dataList.size}
这个适配器的代码也不难,就是 RecyclerView 的根本用法。
咱们晓得在 MVC 架构中 Activity 也承当了视图的作用,Activity 须要去初始化布局,代码如下所示:
class MainActivity : AppCompatActivity() {
private lateinit var adapter: MvcRecyclerAdapter
private val mList = ArrayList<Data>()
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()}
private fun initView() {val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
adapter = MvcRecyclerAdapter(mList, this)
recyclerView.adapter = adapter
}
}
创立 Model 层
咱们须要将在 Model 层去申请数据,而后通过接口的形式将数据传递进来,具体代码如下所示:
class OkhttpModel {
private val url = "https://gank.io/api/v2/data/category/Girl/type/Girl/page/2/count/10"
private lateinit var listener : OnOkhttpListener
fun getData(mListener: OnOkhttpListener) {
listener = mListener
thread {val okHttpClient = OkHttpClient()
val request = Request.Builder().get().url(url).build()
okHttpClient.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {listener.onFail(e.message.toString())
}
override fun onResponse(call: Call, response: Response) {val responseData = response.body?.string()
responseData?.let {val dataBean = Gson().fromJson(responseData, DataBean::class.java)
listener.onSuccess(dataBean)
}
}
})
}
}
interface OnOkhttpListener {fun onSuccess(bean: DataBean)
fun onFail(msg: String)
}
}
创立 Controller 层
Android MVC 架构中 Controller 层就是 Activity 或者 Fragment,所以咱们须要在 Activity 中进行逻辑解决,代码如下所示:
class MainActivity : AppCompatActivity() {
private lateinit var adapter: MvcRecyclerAdapter
private var mList = ArrayList<Data>()
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()}
private fun initView() {val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
adapter = MvcRecyclerAdapter(mList, this)
recyclerView.adapter = adapter
loadData()}
private fun loadData() {val model = OkhttpModel()
model.getData(object : OkhttpModel.OnOkhttpListener {override fun onSuccess(bean: DataBean) {
bean.data.forEach {mList.add(it)
}
runOnUiThread {adapter.notifyDataSetChanged()
}
}
override fun onFail(msg: String) {Toast.makeText(this@MainActivity, msg, Toast.LENGTH_SHORT).show()}
})
}
}
到此为止,一个残缺的 MVP 架构的 App 就做完了。
小结
架构永远是要服务于业务的,不要为了设计而设计,否则反而会升高开发效率,比方一个 App 中只有几个文件,齐全不须要架构,其实下面的例子齐全能够把申请网络数据的代码放到 Activity 中,这样咱们就不须要 Model 层。我下面退出 Model 层只是为了演示 MVC 架构模式的写法。
MVC 模式的长处就是简略不便,然而它的毛病同样显著,随着界面的增多和逻辑复杂度进步,Activity 会显得非常臃肿,一个 Activity 可能有几千行代码,使得保护起来相当艰难。
为了解决上述 MVC 模式存在的问题,拆散 Activity 中的 View 层和 Controller 层的职责,从而对 Activity 代码量进行优化、瘦身,所以就呈现了 MVP 模式,这个模式咱们下次再讲。
源码
源码 已上传到 github,有须要的自取。