MVVM 最完整架构解析及 Jetpack 架构组件的使用

MVVM 架构图

谈到 MVVM 架构,不得不祭出官方的架构图,架构图能帮助我们更好地理解,如下所示:
在这里插入图片描述
MVVM 和 MVP 的区别
MVP 中 V 层和 P 层互相持有对方的引用,在V 层调用 P 层逻辑后,P 层回调V 层的相应方法更新 UI。

而在 MVVM 中,上层只依赖直接下层,不能跨层持有引用,那 View 层调用 ViewModel 处理数据后,又如何更新自己呢?

答案就在 ViewModel 中的 LiveData,这是一种可观察的数据类型,在 View 层中观察者 Observer 对需要的数据进行订阅,当数据发生变化后,观察者 Observer 的回调方法 onChanged() 中会收到新的数据,从而可以更新 UI。

Jetpack 架构组件

Jetpack 是 Google 为我们提供的架构组件,对于这些组件,我有以下理解和使用心得:

DataBinding
适用于数据繁杂的页面,可以减少大量 java 代码。xml 中可以做出类似于VUE 那样的数据双向绑定。同时可以直接调用控件id名称直接写UI逻辑代码不用写findviewById,也不用通过butterknife来注解实现findviewById的节省。
ViewModel
管理 Activity 或 Fragment 的数据
创建于Activity 或 Fragment 内,页面被销毁前,ViewModel 会一直存在
如果因配置变化导致页面销毁,ViewModel 不会销毁,它会被用于新的页面实例
一般在 ViewModel 中配合 LiveData 使用
一般用 ViewModelProviders 获取 ViewModelProvider,再用它的 get() 方法获取 ViewModel
在 get() 方法中会调用 Factory 的 create() 方法创建 ViewModel
Lifecycles
管理你的 Activity 和 Fragment 生命周期。
不用再通过写回调监听来感知Activity 和 Fragment 生命周期的变化来做相应的处理动作
LiveData
基于生命周期的消息订阅组件,不会发生内存泄漏,不用反注册。

MVVM 案例实战

下面根据我的开源项目 Jetpack_MVVM进一步讲解 MVVM 架构的运用,以下所有代码均来自于该项目

1、基类封装

专门针对MVVM模式打造的BaseActivity、BaseFragment、BaseViewModel,在View层中不再需要定义ViewDataBinding和ViewModel,直接在BaseActivity、BaseFragment上限定泛型即可使用。

public abstract class BaseActivity<V extends ViewDataBinding, VM extends BaseViewModel> extends RxAppCompatActivity implements LifecycleProvider<ActivityEvent> {
    protected V binding;
    protected VM viewModel;
    /**
     * 注入绑定
     */
    private void initViewDataBinding(Bundle savedInstanceState) {
        //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包
        binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));
        viewModelId = initVariableId();
        viewModel = initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数,则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(modelClass);
        }
        ...........................
    }
    /**
     * 创建ViewModel
     *
     * @param <T>
     * @return
     */
    protected <T extends ViewModel> T createViewModel(@NonNull Class<T> modelClass) {
        if (mActivityProvider == null) {
            mActivityProvider = new ViewModelProvider(this);
        }
        return mActivityProvider.get(modelClass);
    }
    ...............
}

2、网络请求框架封装

retrofit+okhttp+rxJava负责网络请求;gson负责解析json数据;rxlifecycle负责管理view的生命周期;与网络请求共存亡;
RetrofitClient
NetWorkManager
这两个类分别封装了Retrofit的相关配置和具体的使用方法。
RetrofitClient 中对相关参数进行相关初始化配置,拦截配置,以及参数加密配置。

public class RetrofitClient {
    //超时时间
    private static final int DEFAULT_TIME_OUT = 10;//超时时间 70s
    private static final int DEFAULT_READ_TIME_OUT = 10;


    //缓存时间
    private static final int CACHE_TIMEOUT = 10 * 1024 * 1024;
    //服务端根路径
    public static String baseUrl = "http://rap2.taobao.org:38080/app/mock/259908/";

    private static Context mContext = App.getContext();

    private static OkHttpClient okHttpClient;
    private static Retrofit retrofit;

    private Cache cache = null;
    private File httpCacheDirectory;

    private static class SingletonHolder {
        private static RetrofitClient INSTANCE = new RetrofitClient();
    }

    public static RetrofitClient getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private RetrofitClient() {
        this(baseUrl, null);
    }

    private RetrofitClient(String url, Map<String, String> headers) {

        if (TextUtils.isEmpty(url)) {
            url = baseUrl;
        }

        if (httpCacheDirectory == null) {
            httpCacheDirectory = new File(mContext.getCacheDir(), "goldze_cache");
        }

        try {
            if (cache == null) {
                cache = new Cache(httpCacheDirectory, CACHE_TIMEOUT);
            }
        } catch (Exception e) {
            LogUtils.e("Could not create http cache", e);
        }
        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory();
        okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJarImpl(new PersistentCookieStore(mContext)))
                .cache(cache)
                .addInterceptor(new BaseInterceptor(headers))
                .addInterceptor(new CacheInterceptor(mContext))
                .addInterceptor(commonHeader())
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .addInterceptor(new LoggingInterceptor
                        .Builder()//构建者模式
                        .loggable(BuildConfig.
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值