我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情
简介
一个App总是由展示层、业务层、数据层组成的。所有的架构设计,不管是MVC、MVP还是MVVM、AAC等,都是在围绕着这三个层级进行的设计。
MVC的V就是展示层,由XML和View组成;
C就是业务层,由Activity和Fragment构成;
M就是数据层,是获取数据的部分。
优点
- 上手快。新建工程的时候,Android已经分配了XML和Activity,这样直接对应View层和Controller层,我们只需要增加model模块处理好数据即可。
- 由于Controller层承担了较多的处理j界面展示和数据处理的功能,相对来说简化业务模块和功能模块的划分。
缺点
- View层以XML作为实现,其控制能力太弱,比如动态地更新View状态就不能通过View来实现;
- Control层既负责处理UI更新,又负责处理业务,职责臃肿;
- Control层未做到完全将View层和Model层隔离,因为View层可以直接访问Model层(如自定义View类),导致View层和Model层耦合性增强;
- Control层负担太重,导致代码过多,后期开发、测试及维护困难;
适用范围
App需求功能不多,版本迭代不频繁,需要段时间内完成。
实例
View:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/base_bg">
<TextView
android:id="@+id/tv_activity_mvc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
Controller:
public class MVCActivity extends BaseActivity {
RetrofitManager mRetrofitManager;
@BindView(R.id.tv_activity_mvc)
TextView mTextView;
@Override
protected int getContentViewLayoutID() {
return R.layout.activity_architecture_mvc_activity;
}
@Override
protected void initViewsAndEvents(Bundle savedInstanceState) {
mTextView.setText("I don't do anything, but this is a MVC show anyway. Click me!");
mRetrofitManager = new RetrofitManager();
}
@OnClick(R.id.tv_activity_mvc)
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_activity_mvc:
mRetrofitManager.createApi(MyApplication.getInstance().getApplicationContext(), GankApis.class)
.getHistoryDate()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BaseObserver<GankRes<List<String>>>() {
@Override
public void onError(ApiException exception) {
LogUtil.e(TAG, "error:" + exception.getMessage());
}
@Override
public void onSuccess(GankRes<List<String>> listGankRes) {
LogUtil.i(TAG, listGankRes.getResults().toString());
if (!MVCActivity.this.isFinishing() && !MVCActivity.this.isDestroyed()) {
mTextView.setText("yes, I get it from net!");
}
}
});
break;
}
}
}
Model
public class RetrofitManager {
private static final String TAG = "RetrofitManager";
private static Retrofit singleton;
private static OkHttpClient okHttpClient = null;
private static String BASE_URL = "http://127.0.0.1";
private void init() {
initOkHttp();
}
public RetrofitManager() {
init();
}
private void initOkHttp() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
// Log信息拦截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//这里可以选择拦截级别
//设置 Debug Log 模式
builder.addInterceptor(loggingInterceptor);
//配置SSL证书检测
builder.sslSocketFactory(SSLSocketClient.getNoSSLSocketFactory());
builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
}
//错误重连
builder.retryOnConnectionFailure(true);
okHttpClient = builder.build();
LogUtil.i(TAG, "initOkHttp:getNoSSLSocketFactory");
}
public static void initBaseUrl(String url) {
BASE_URL = url;
LogUtil.i(TAG, " base_url ->" + BASE_URL);
}
/**
* @param context Context
* @param clazz interface
* @param <T> interface实例化
* @return
*/
public static <T> T createApi(Context context, Class<T> clazz) {
if (singleton == null) {
synchronized (RetrofitManager.class) {
if (singleton == null) {
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())//定义转化器,用Gson将服务器返回的Json格式解析成实体
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());//关联Rxjava
singleton = builder.build();
}
}
}
return singleton.create(clazz);
}
}