热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidMVVM+DataBinding结合Dagger2进行开发

前言在我的前几篇文章中,简单学习了以下内容:AndroidDataBinding使用总结(一)DataBinding的环境配置和基本使用AndroidDataBinding使用

前言

在我的前几篇文章中,简单学习了以下内容:

Android DataBinding使用总结 (一) DataBinding的环境配置和基本使用

Android DataBinding使用总结(二) DataBinding的所有基本使用方法

Android DataBinding使用总结(三) DataBinding展示RecyclerView列表

Android DataBinding使用总结(四) DataBinding的多类型列表展示

Android DataBinding使用总结(五)结合MultiType展示多类型列表

今天将前段时间学习的DataBinding结合Dagger2进行MVVM的架构模式进行一个简单的界面开发。

阅读本文需要了解的库:Dagger2、DataBinding的基本使用。

Dagger2作为强大的依赖注入库,可以给我们平时的开发效率带来极大的提升,如果没有了解过的请可以参考我的相关文章,本文不再叙述:

我的相关文章,从基础使用到源码分析:

Android 神兵利器Dagger2使用详解(一)基础使用

Android 神兵利器Dagger2使用详解(二)Module&Component源码分析

Android 神兵利器Dagger2使用详解(三)进阶篇,不可自拔爱上Dagger2

源码:

「GitHub」 Dagger2_Sample源码,配合上述文章学习效果更佳

其他相关学习资料:

Android Dagger依赖注入框架浅析
http://www.tuicool.com/articles/Nf6Njy
Dagger——Android上的依赖注入框架
https://my.oschina.net/rengwuxian/blog/287892?p=2&temp=1488510429911
Dagger - 快速的依赖注入器-官方文档翻译
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0213/2478.html
Dagger 2: Step To Step
http://www.jianshu.com/p/7505d92d7748
使用Dagger 2进行依赖注入
http://codethink.me/2015/08/06/dependency-injection-with-dagger-2/
Dagger2 使用详解
http://blog.csdn.net/u013163564/article/details/51847784
详解Dagger2
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0519/2892.html

一、成果:

这里写图片描述

很简单的demo,一共实现了两种需求,修改界面数据,同时还有网络请求电影信息(API接口from@豆瓣 ,感谢其提供的开发者平台)。

对于MVVM(Model+View+ViewModel)架构设计及思想,请参考这篇文章:

如何构建Android MVVM应用程序 @Kelin大神

有幸拜读了他的源码,收获颇多。

二、代码展示

0、依赖注入Dagger2相关代码(含Model层):

经常使用Dagger2的朋友们应该很熟悉了,代码就不写上去了,需要提到一点的是,依赖注入的ServiceManager实际上就是Model层,代表着网络请求电影数据:

public class ServiceManager {

MovieService movieService;

public ServiceManager() {
init();
}

private void init() {

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
if (Constants.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
}
OkHttpClient client = builder.build();

movieService = new Retrofit.Builder()
.baseUrl(Constants.API.BASE_DOUBAN)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client)
.build()
.create(MovieService.class);
}

public Observable getMovieInfoTest() {
return getMovieInfo(String.valueOf(25937854));
}

/**
* 获得对应电影ID的电影信息
*
* @param movieId
* @return
*/

public Observable getMovieInfo(String movieId) {
return movieService.getMovieInfo(movieId);
}
}

因为Dagger2并不是本文的重点,因此如果要看更多源码的话,请参考Github传送门,点我查看更多源码

1、Activity+xml布局文件(xml代表View层)

先看下Activity:

public class A06MvvmActivity extends BaseMvvmActivity<A06ActivityMvvmBinding, A06MvvmViewModel> {

@Inject
A06MvvmViewModel mViewModel;

//依赖注入&&DataBinding绑定
@Override
protected void inject() {
A06Component compOnent= DaggerA06Component.builder()
.appComponent(ComponentHolder.getComponent())
.a06Module(new A06Module(this))
.build();
component.injectActivity(this);
component.injectViewModel(mViewModel);

mBinding.setActivity(this);
mBinding.setViewModel(mViewModel);
}

//设置layout布局
@Override
protected int getLayoutRes() {
return R.layout.a06_activity_mvvm;
}

}

其中的BaseActivity封装了一些简单的逻辑:

public abstract class BaseMvvmActivity<T extends ViewDataBinding, D extends BaseViewModel> extends AppCompatActivity {

protected T mBinding;
protected D mViewModel;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDataBinding();
inject();
}

protected void initDataBinding() {
int layoutId = getLayoutRes();
mBinding = DataBindingUtil.setContentView(this, layoutId);
}

/**
* 初始化DataBinding 和 Dagger2依赖注入
*/

protected abstract void inject();

/**
* 传入布局文件
* @return 基类会自动生成对应的DataBinding供导出类使用
*/

protected abstract int getLayoutRes();

@Override
protected void onDestroy() {
if (mBinding != null)
mBinding.unbind();

super.onDestroy();
}
}

重要的布局文件:


<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data>

<variable
name="activity"
type="com.mei_husky.samplemvvm.view.activity.A06MvvmActivity" />


<variable
name="viewModel"
type="com.mei_husky.samplemvvm.viewmodel.A06MvvmViewModel" />


data>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">



<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{`学生姓名:` + viewModel.student.get().name}" />


<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.changeName()}"
android:text="点击修改Student姓名" />


<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.getMovieInfo()}"
android:text="点击请求电影信息" />


<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.movieInfo.get() == null ? `没有电影信息` : viewModel.movieInfo.get().getSummary()}" />


LinearLayout>

layout>

可以看到,所有界面逻辑的处理,我们都交给了viewModel,Activity实际上并没有染指任何修改UI的代码。

2、viewModel层,直接和xml交互,不再需要Activity

public class A06MvvmViewModel extends BaseViewModel {

public final ObservableField student = new ObservableField<>();
public final ObservableField movieInfo = new ObservableField<>();

@Inject
A06MvvmActivity activity;
@Inject
SharedPreferences sp;
@Inject
ServiceManager serviceManager;

public A06MvvmViewModel() {
student.set(new Student("qingmei2", 18));
}

public void changeName() {
student.get().name.set(student.get().name.get() + "X");
}

/**
* 网络请求电影数据,直接调用Model层获取数据
*/

public void getMovieInfo() {
serviceManager.getMovieInfoTest()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(movieInfoModel -> movieInfo.set(movieInfoModel));
}
}

//BaseViewModel中可以添加一些公共代码,在本demo中不涉及
public class BaseViewModel {

}

梳理一下,我们通过将viewModel通过DataBinding和xml布局绑定后,实际上数据的处理和界面的展示都已经「摆脱」了传统的Activity,在viewModel通过Model获得数据后,xml中直接根据Observable的对象观察到变化并立即更新数据,可以说是非常方便,同时一些界面的UI修改不再需要在activity中通过setText,setBackGround,setVisibility等方法去处理了,直接交给xml去处理,代码看起来非常清晰,同时耦合性也比较低。

总结

需求实现,我们可以看到,因为Activity并没有接触UI修改的逻辑,因此相比MVP设计模式,我们M-V-VM之间的耦合性更低,并且对于单元测试来说配合Mockito更加高效便捷,同时也摆脱了MVP中令人望而生畏的接口数量,因此还是有可鉴之处的。

参考文档

DataBinding 谷歌官方文档

如何构建Android MVVM应用程序 @Kelin大神

本文源码地址

Github传送门,点我查看源码

该demo包含本文中所有代码但不仅限于:

使用了 Mvvm+DataBinding 搭建的DemoApp

——DataBinding的入门使用以及引导界面

——Databinding的使用

——RecyclerView中使用dataBinding进行列表展示

——RecyclerView中使用dataBinding展示多类型列表

——MultiType库+DataBinding展示RecyclerView多类型列表

——简单搭建MVVM+DataBinding+Dagger2的界面


推荐阅读
  • 本课程详细解析了Spring AOP的核心概念及其增强机制,涵盖前置增强、后置增强和环绕增强等类型。通过具体示例,深入探讨了如何在实际开发中有效运用这些增强技术,以提升代码的模块化和可维护性。此外,还介绍了Spring AOP在异常处理和性能监控等场景中的应用,帮助开发者更好地理解和掌握这一强大工具。 ... [详细]
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • 智能制造数据综合分析与应用解决方案
    在智能制造领域,生产数据通过先进的采集设备收集,并利用时序数据库或关系型数据库进行高效存储。这些数据经过处理后,通过可视化数据大屏呈现,为生产车间、生产控制中心以及管理层提供实时、精准的信息支持,助力不同应用场景下的决策优化和效率提升。 ... [详细]
  • 本文深入探讨了 Vue.js 中异步组件的应用与优化策略。首先,文章介绍了异步组件的基本概念及其在现代前端开发中的重要性。为了确保最佳实践,建议使用 Webpack 作为模块打包工具,因为 Browserify 默认不支持异步组件的加载。接着,详细解释了异步组件的使用方法,并提供了官方文档的相关链接以供参考。此外,文章还讨论了多种优化技巧,包括代码分割、懒加载和性能调优,以提升应用的整体性能和用户体验。 ... [详细]
  • 本文探讨了在Android应用中实现动态滚动文本显示控件的优化方法。通过详细分析焦点管理机制,特别是通过设置返回值为`true`来确保焦点不会被其他控件抢占,从而提升滚动文本的流畅性和用户体验。具体实现中,对`MarqueeText.java`进行了代码层面的优化,增强了控件的稳定性和兼容性。 ... [详细]
  • 深入解析Tomcat:开发者的实用指南
    深入解析Tomcat:开发者的实用指南 ... [详细]
  • MySQL性能优化与调参指南【数据库管理】
    本文详细探讨了MySQL数据库的性能优化与参数调整技巧,旨在帮助数据库管理员和开发人员提升系统的运行效率。内容涵盖索引优化、查询优化、配置参数调整等方面,结合实际案例进行深入分析,提供实用的操作建议。此外,还介绍了常见的性能监控工具和方法,助力读者全面掌握MySQL性能优化的核心技能。 ... [详细]
  • 如果你对项目管理和系统架构感兴趣,欢迎关注微信订阅号“softjg”,加入我们这个PM和架构师的大家庭。本文将探讨编写高质量软件架构文档的重要性及其优势。良好的架构文档不仅能够促进不同利益相关者之间的沟通与理解,还能为项目的长期维护和扩展提供坚实的基础。通过详细记录系统的设计决策和关键组件,架构文档能够确保团队成员在项目周期内保持一致性和高效协作。 ... [详细]
  • 本文深入探讨了Spring Cloud Eureka在企业级应用中的高级使用场景及优化策略。首先,介绍了Eureka的安全配置,确保服务注册与发现过程的安全性。接着,分析了Eureka的健康检查机制,提高系统的稳定性和可靠性。随后,详细讨论了Eureka的各项参数调优技巧,以提升性能和响应速度。最后,阐述了如何实现Eureka的高可用性部署,保障服务的连续性和可用性。通过这些内容,开发者可以更好地理解和运用Eureka,提升微服务架构的整体效能。 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • POJ 1696: 空间蚂蚁算法优化与分析
    针对 POJ 1696 的空间蚂蚁算法进行了深入的优化与分析。本研究通过改进算法的时间复杂度和空间复杂度,显著提升了算法的效率。实验结果表明,优化后的算法在处理大规模数据时表现优异,能够有效减少计算时间和内存消耗。此外,我们还对算法的收敛性和稳定性进行了详细探讨,为实际应用提供了可靠的理论支持。 ... [详细]
  • 深入解析 AngularJS 表达式的应用与优化技巧
    本文深入探讨了AngularJS表达式的应用及其优化策略。在AngularJS中,表达式主要通过$digest循环进行自动解析,但在某些场景下,手动解析表达式也是必要的。文章详细介绍了如何利用$parse服务实现手动解析,并提供了多种优化技巧,以提高应用性能和响应速度。 ... [详细]
  • 内网渗透技术详解:PTH、PTT与PTK在域控环境中的应用及猫盘内网穿透配置
    本文深入探讨了内网渗透技术,特别是PTH、PTT与PTK在域控环境中的应用,并详细介绍了猫盘内网穿透的配置方法。通过这些技术,安全研究人员可以更有效地进行内网渗透测试,解决常见的渗透测试难题。此外,文章还提供了实用的配置示例和操作步骤,帮助读者更好地理解和应用这些技术。 ... [详细]
  • RangerApi之User管理在大数据平台之权限管理组件-AapcheRanger一文中我们了解了Ranger以及安装部署过程以及Admin可视化界面的使用。除了可以在可视化的R ... [详细]
  • 开发笔记:深度探索!Android之OkHttp网络架构源码解析
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了深度探索!Android之OkHttp网络架构源码解析相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
柳绿海蓝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有