mvp架构,dagger2,butterknife的使用

2024-01-01 13:58

本文主要是介绍mvp架构,dagger2,butterknife的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

mvp架构,dagger2,butterknife的使用

  • butterKnife框架简介
    • ButterKnife的优势
    • ButterKnife的使用
  • dagger2
    • Dagger2是什么?
    • 框架说明
    • Dagger2与butterknife区别
    • 依赖注入
    • Dagger2注解说明
    • Dagger2基本使用:
    • Dagger2复杂使用:
    • 小结
  • MVP
    • 步骤
    • Androidx版本MVP
    • Android中的MVP

butterKnife框架简介

注于Android系统的View注入框架,当一个布局十分复杂时,需要引入执行大量的 findViewById代码来找到View的对象,有了ButterKnife可以很轻松的省去这些步骤。是大 神JakeWharton的力作,目前使用很广。最重要的一点,使用ButterKnife对性能基本没 有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的 class。项目集成起来也是特别方便,使用起来也是特别简单。
https://github.com/JakeWharton/butterknife

ButterKnife的优势

  1. 强大的View绑定事件和资源文件的绑定
  2. 使用的便捷性上,剔除了原始绑定时候的复杂性
  3. 由于大多数的注解都是在编译期,所以不会影响程序运行的效率
  4. 代码清晰,可读性相对来说要强很多

ButterKnife的使用

1.导入依赖
2.声明控件变量->访问修饰符不能为private->影响注入控件对象
3.使用@BindView绑定控件
4.使用@Onclik添加点击事件
依赖

implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

Activity

package com.example.studio_skill3;import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;public class MainActivity extends AppCompatActivity {@BindView(R.id.bt_title1)Button button;Unbinder bind;private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Unbinder bind = ButterKnife.bind(this);Log.i(TAG, "onCreate: 按钮"+button);FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();fragmentTransaction.add(R.id.liner_id,new MyFragment()).commit();}@OnClick({R.id.bt_title1,R.id.bt_title2,R.id.bt_title3})public void onclick(View view){if (view.getId() == R.id.bt_title1){Log.i(TAG, "onclick: 按钮点击");}else if (view.getId() == R.id.bt_title2){Toast.makeText(this, "按钮被点击", Toast.LENGTH_SHORT).show();}else if (view.getId() == R.id.bt_title3){Toast.makeText(this, "一生所爱", Toast.LENGTH_SHORT).show();}}@Overrideprotected void onDestroy() {super.onDestroy();bind.unbind();}
}

dagger2

Dagger2是什么?

Dagger2是Dagger的升级版,是一个依赖注入框架,第一代由大名鼎鼎的 Square公司共享出来,第二代则是由谷歌接手后推出的,现在由Google接手维 护.

框架说明

减少样板代码;提高重用性,测试性,可维护性.
用@Inject写到对象类的构造函数上面,要用的时候直接注入对象,避免new对象,造成强耦合。且可以加上注释@Singleton形成单例;
以@module和@provides为基础,可以任意注入对象,且可以带参操作。Module里面若是要有其他Module,要在includes里写好,@Module除了include,还有injects参数指定注入位置,library指定是否需要外部库,complete是否是完整module(含有外部module依赖则不完整)。最后在注入目的地,通过ObjectGraph(对象图表)形成依赖关系,具体操作方式,ObjectGraph对象,并调用方法create(Module).inject(注入对象);则可以直接用@inject注入目标对象类里。
在这里插入图片描述

Dagger2与butterknife区别

Buffer knife目的为注入到view,所以能够在非activity里面注入,也能注入到inflate的views里面;
Dagger能够注入到任何你想要的对象,只要其在module类中。或者它是构造器。但是缺少对方法和字段的注入支持;
Buffer knife只是避免样板代码,findViewById,仅此而已,所以不能算是一个真正的注入。只是一个view的代言;
对于Dagger我们可以把它当做应用中的一个模块,
负责为其它模块提供实例并且注入依赖关系。那是它的基本职责。模块的创建位于我们应用中的一个点上,这样我们可以拥有完全的控制权。Dagger
Leiva说,特别适合用在低端设备上,因为它没有采取反射而使用了预编译技术,因为基于反射的DI非常占用资源和耗时。Dagger或许不是最理想的依赖注入框架,但Leiva认为,它是最高效的。

依赖注入

implementation 'com.google.dagger:dagger:2.19'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'

Dagger2注解说明

@Inject
Inject主要有两个作用,一个是使用在构造函数上,通过标记构造函数让Dagger2来使用(Dagger2通过Inject标记可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来)从而提供依赖,另一个作用就是标记在需要依赖的变量让Dagger2为其提供依赖。
@Provide
用Provide来标注一个方法,该方法可以在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Injection的变量赋值。provide主要用于标注Module里的方法
@Module
用Module标注的类是专门用来提供依赖的。有的人可能有些疑惑,看了上面的@Inject,需要在构造函数上标记才能提供依赖,那么如果我们需要提供的类构造函数无法修改怎么办,比如一些jar包里的类,我们无法修改源码。这时候就需要使用Module了。Module可以给不能修改源码的类提供依赖,当然,能用Inject标注的通过Module也可以提供依赖
@Component一般用来标注接口,被标注了Component的接口在编译时会产生相应的类的实例来作为提供依赖方和需要依赖方之间的桥梁,把相关依赖注入到其中。
@Scope:作用域,Dagger2通过自定义注解来限定作用域,有一个默认的作用域注解@Singleton,通常在Android中用来标记在App整个生命周期内存活的实例。也可以自定义一个@PerActivity、@PerFragment注解,用来表明实例生命周期与Activity、Fragment一致。我们可以自定义作用域的粒度(比如@PerUser等等)。
@Qualifier:限定符。当一个类的类型不足以标示一个依赖的时候,我们就可以用这个注解。例如,我们有两个@Provide注解的方法都需要一个String参数,那么在提供依赖的方法上面就可以通过自定义标识“@ForData”或者“@ForImage”来进行区别Dagger2里面已经存在一个限定符@Named注解,通过@Named(”xxxxx”)就可以进行标识。
@SubComponent:如果我们需要父组件全部的提供对象,这时我们可以用包含方式而不是用依赖方式,相比于依赖方式,包含方式不需要父组件显式显露对象(依赖方式只能拿到暴露出的实例),就可以拿到父组件全部对象。且SubComponent只需要在父Component接口中声明就可以了
@Named(@)因为Dagger2 的以来注入是使用类型推断的,所以同一类型的对象就无法区分,可以使用@Named注解区分同一类型对象,可以理解为对象的别名!

Dagger2基本使用:

创建Inject2类并使用@Inject标记构造方法,向其他类提供依赖;
创建Inject1类声明Inject2变量并使用Inject标注;
Inject1下创建show方法,调用inject2下的show方法创建InjectComponent接口使用Component标注;
创建inject方法向inject1提供依赖inject2
在Inject1的show方法中使用DaggerInjectComponent.builder().build().inject(this);获取依赖

Dagger2复杂使用:

创建ShowUtils类负责具体显示逻辑;
创建ShowInject类使用Inject标签标记ShowUtils变量引入依赖;
创建ShowModules类使用Modules标签标注管理方法中的Provides标签标注的方法并使用new关键字创建被依赖类的对象;
创建ModulesComponent接口使用@Component(modules = {ShowModules.class})
声明管理类ShowModules并创建提供依赖方法

小结

Dagger2->依赖注入框架->项目中注入类对象
->为什么使用dagger2?解耦合->在Activity不直接创建对象
基本使用:1.创建ShowInjectUtils
2.创建show方法->使用当前类下的方法
3.重写构造方法->构造方法上添加@Inject标签->当前类对象要通过dagger2注入到其他类中
4.MainActivity下编写变量使用@Inject接收注入对象
5.ShowCompont(dagger2注入对象桥梁)
6.编写抽象方法inject->声明对象注入到哪里去
7.构建项目->锤
8.调用Dagger2
进阶使用:1.创建ShowModulesInjectUtils
2.创建show方法->使用当前类下方法
3.重写构造方法->构造方法上添加@Inject标签
4.创建仓库类ShowModules->向桥梁提供对象
5.创建showProvider方法->向桥梁提供对象
6.创建桥梁
7.MainActivity下声明使用
8.构建
9.使用

public class ShowInject {@Injectpublic ShowInject() {}public void show(){Log.i("TAG", "show: 你好啊");}
}
import dagger.Component;@Component
public interface ShowCompont {void inject(MainActivity mainActivity);
}

进阶使用

import javax.inject.Inject;public class ShowModules {@Injectpublic ShowModules() {}public void show(){Log.i("TAG", "show: 哈哈哈");}
}
import dagger.Module;
import dagger.Provides;@Module
public class ShowModules1 {@Providespublic ShowModules getInstance(){return new ShowModules();}
}
import dagger.Component;@Component(modules = ShowModules1.class)
public interface ShowModulesComponent {void inject(MainActivity mainActivity);
}

创建完后锤
自动生成对象:\build\generated\source\apt\debug\com\example\dagger2_practice\di\DaggerShowComponent.java

//有供有求public class MainActivity extends AppCompatActivity {@Injectpublic ShowInject showInject;@Injectpublic ShowModules showModules;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);DaggerShowCompont.builder().build().inject(this);DaggerShowModulesComponent.builder().build().inject(this);}public void button(View view) {showInject.show();}public void button2(View view) {showModules.show();}
}

MVP

MVP框架-SDK28
MVPAMS放置地址
D:\SoftWare\Android\Android Studio\plugins\android\lib\templates\gradle-projects
在这里插入图片描述

步骤

1.分包
mvp ----> model view presenter contract
di ----> component modules
2.对应解析数据的实体类
entity
3.Api请求数据
Api
4.contract订阅
IView与IModel的接口实现
5.model 具体请求方法 继承自BaseModel实现订阅下的IXXXModel
6.XXXPresenter继承自BasePresenter
7.di包modules
8.di包component
9.MainActivity 继承BaseActivity 实现IView接口
转载:
https://blog.csdn.net/weixin_44419661/article/details/98957127

Androidx版本MVP

Android中的MVP

MVP模式是MVC模式在Android上的一种变体,要介绍MVP就得先介绍 MVC。在MVC模式中,Activity应该是属于View这一层。而实质上,它既承担 了View,同时也包含一些Controller的东西在里面。这对于开发与维护来说不 太友好,耦合度大高了。把Activity的View和Controller抽离出来就变成了View 和Presenter,这就是MVP模式。 按照MVC的分层,Activity和Fragment(后面只说Activity)应该属于View 层,用于展示UI界面,以及接收用户的输入,此外还要承担一些生命周期的工 作。Activity是在Android开发中充当非常重要的角色,特别是TA的生命周期的 功能,所以开发的时候我们经常把一些业务逻辑直接写在Activity里面,这非常 直观方便,代价就是Activity会越来越臃肿,超过1000行代码是常有的事,而且 如果是一些可以通用的业务逻辑(比如用户登录),写在具体的Activity里就意 味着这个逻辑不能复用了。如果有进行代码重构经验的人,看到1000+行的类 肯定会有所顾虑。因此,Activity不仅承担了View的角色,还承担了一部分的 Controller角色,这样一来V和C就耦合在一起了,虽然这样写方便,但是如果 业务调整的话,要维护起来就难了,而且在一个臃肿的Activity类查找业务逻辑 的代码也会非常蛋疼,所以看起来有必要在Activity中,把View和Controller抽 离开来,而这就是MVP模式的工作了。
MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成 Presenter接口,Model类还是原来的Model。
分离了视图逻辑和业务逻辑,降低了耦合
Activity只处理生命周期的任务,代码变得更加简洁
视图逻辑和业务逻辑分别抽象到了View和Presenter的接口中去,提 高代码的可阅读性
Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单 元测试
把业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致 Activity的资源无法被系统回收从而引起内存泄露和OOM
创建MVP模式项目
在setting 的plugin选项搜索安装MVPHelper 创建一个presenter包内新建 Presenter接口使用快捷键 Alt + Insert, 选择 Mvp Helper 即可生成对应文件.
有中文路径会报错,添加

org.gradle.jvmargs=-Dfile.encoding=UTF-8

在这里插入图片描述

这篇关于mvp架构,dagger2,butterknife的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/559464

相关文章

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

Ubuntu如何分配​​未使用的空间

《Ubuntu如何分配​​未使用的空间》Ubuntu磁盘空间不足,实际未分配空间8.2G因LVM卷组名称格式差异(双破折号误写)导致无法扩展,确认正确卷组名后,使用lvextend和resize2fs... 目录1:原因2:操作3:报错5:解决问题:确认卷组名称​6:再次操作7:验证扩展是否成功8:问题已解

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核