目录
大家好!
作为 Android 程序猿,MVC 应该是我们第一个接触的架构吧,从开始接触 Android 那一刻起,我们就开始接触它,可还记得我们写的第一个 App 代码的样子?
架构设计的目的
通过设计使程序模块化,模块内 高内聚、模块间 低耦合,提高开发效率,便于复用及后续维护。
对 MVC 的理解
上图是 MVC 的架构图,我们都知道,MVC架构中 M 代表 Model(模型)、V 代表 View(视图)、C 代表 Controller(控制器)。它们的职责分别是:
- View 负责接收用户的输入事件,然后将事件传递给 Controller;
- Controller 收到事件后,会进行业务处理,通知 Model 请求数据;
- Model 拿到数据后返回给 Controller 进行后续处理,或者通知 View 更新 UI。
Android 中 MVC 的问题
不幸的是,在 Android 中,通常由 Activity 充当 Controller,与此同时,由于 xml 的弱功能性,导致 Activity 还需要负责视图的显示,所以原本是负责初始化页面的 Activity,就变成了 View 和 Controller 的载体,导致这两部分内容耦合在 Activity 中。后果就是Activity 越来越臃肿、难以维护。这就违反了架构设计的初衷,所以就有了后来的MVP。
试吃个小李子
点击按钮,请求 wanandroid 网站的 banner 接口数据,请求成功后更新到UI上显示接口数据
View
一个Button,点击请求接口数据
一个TextView,用于回显接口返回的数据
activity_main.xml
java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_get_banner_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getBannerInfo"
android:text="@string/get_banner_info" />
<TextView
android:id="@+id/tv_banner_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Model
请求接口
Repository.java
java
public final class Repository {
private ApiService mService;
private Repository() {
createService();
}
public static Repository getInstance() {
return SingletonHolder.sInstance;
}
private static final class SingletonHolder {
private static final Repository sInstance = new Repository();
}
/**
* 请求 banner 数据
*/
public void getBanners(ResponseCallback<List<Banner>> callback) {
mService.getBanners().enqueue(new Callback<BaseResponse<List<Banner>>>() {
@Override
public void onResponse(Call<BaseResponse<List<Banner>>> call, Response<BaseResponse<List<Banner>>> response) {
BaseResponse<List<Banner>> body = response.body();
if (response.isSuccessful() && body != null) {
if (body.getErrorCode() == 0) {
callback.onSuccess(body.getData());
} else {
callback.onFail(body.getErrorMsg());
}
} else {
callback.onFail(response.message());
}
}
@Override
public void onFailure(Call<BaseResponse<List<Banner>>> call, Throwable throwable) {
callback.onFail(throwable.getMessage());
}
});
}
private void createService() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(HttpConstant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
mService = retrofit.create(ApiService.class);
}
}
Controller
获取数据
更新UI
MainActivity.java
java
public class MainActivity extends AppCompatActivity implements ResponseCallback<List<Banner>> {
private TextView mBannerInfoTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBannerInfoTv = (TextView) findViewById(R.id.tv_banner_info);
}
/**
* 按钮点击事件
* @param view
*/
public void getBannerInfo(View view) {
getBanners();
}
/**
* 获取 banner 数据
*/
private void getBanners() {
Repository.getInstance().getBanners(this);
}
@Override
public void onSuccess(List<Banner> banners) {
if (banners != null && banners.size() > 0) {
showBannerInfo(banners);
}
}
@Override
public void onFail(String msg) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT);
}
/**
* 更新UI
* @param banners
*/
private void showBannerInfo(List<Banner> banners) {
StringBuilder sb = new StringBuilder("wanandroid 官网\nhttps://www.wanandroid.com\n\n");
for(Banner item : banners) {
sb.append(item.getTitle()).append('\n');
}
mBannerInfoTv.setText(sb.toString());
}
}
写在最后:
很荣幸成为一名 Android 程序猿,虽然不是一名合格的猿。一路走来磕磕绊绊,借此感谢帮助过我的人,感谢指点、感恩遇见!