在我们的日常编码的过程中,常常会遇到这种需求。例如:这个版本我们使用okhttp作为网络通信库,如果下个版本我们想要用volley作为网络通信库,那该怎么办呢?我们总不能对使用okhttp的地方一个个改成volley吧!这样得要改到猴年马月啊!因此,通常情况下,我们接入第三方库的时候总会有一个隔离层,方便我们日后切换不同的第三方库。接下来,笔者将手把手演示如何搭建一个隔离层。

技术方案

一般,我们搭建隔离层的技术方案有两种:

  • 使用代理方式实现
  • 使用Hilt反射方式实现

我们首先使用代理的方式来实现隔离层,以切换log为例。

  1. 首先,我们需要针对不同的库,定义一个统一的接口
package com.example.test;public interface ILogCallback {void d(String tag,String msg);void e(String tag,String msg);
}
  1. 实现该接口,例如我们定义了BLog和XLog这两个类,在接口的方法中做不同的实现以示功能的区分。
package com.example.test;import android.util.Log;public class BLog implements ILogCallback{@Overridepublic void d(String tag, String msg) {Log.d("BLog"+tag,msg);}@Overridepublic void e(String tag, String msg) {Log.e("BLog"+tag,msg);}
}
package com.example.test;import android.util.Log;public class XLog implements ILogCallback{@Overridepublic void d(String tag, String msg) {Log.d("XLog"+tag,msg);}@Overridepublic void e(String tag, String msg) {Log.e("XLog"+tag,msg);}
}
  1. 定义一个统一的类,来决定我们要使用的是BLog还是XLog类。
package com.example.test;public class LogHelper {private ILogCallback callback;private static LogHelper helper;private LogHelper() {}public static LogHelper getInstance() {if (helper == null) {helper = new LogHelper();}return helper;}public void init(ILogCallback callback) {this.callback = callback;}public void e(String tag, String msg) {callback.e(tag, msg);}public void d(String tag, String msg) {callback.d(tag, msg);}}

5.在application中初始化

package com.example.test;import android.app.Application;public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();LogHelper.getInstance().init(new XLog());//LogHelper.getInstance().init(new BLog());}
}
package com.example.testimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import javax.inject.Injectclass MainActivity : AppCompatActivity() {@Injectlateinit var student:Studentoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)LogHelper.getInstance().d("MainActivity","Hello World")}
}

这样,我们就只需要更改application中的一句代码就能够灵活地切换BLog和XLog了。

接下来,我们来间接如何使用Hilt来搭建隔离层架构。首先,我们得要搞清楚Hilt究竟是一个什么东西,它与dagger2有什么区别。简单来说,Hilt与Dagger2的关系就是okhttp与retrofit的关系,hilt仅仅只是对dagger2的二次封装而已,为了更加好用,核心的功能还是由dagger2来实现的。
hilt相较于dagger2的最明显特征就是:

  1. 简单
  2. 提供了Android专属的API

学习Hilt,我们需要知道下面几个概念。

  • Hilt组件
    对于您可以从中执行字段注入的每个 Android 类,都有一个关联的 Hilt 组件,您可以在 @InstallIn 注解中引用该组件。每个 Hilt 组件负责将其绑定注入相应的 Android 类。
  • Hilt组件的生命周期
  • 组件作用域
    默认情况下,Hilt 中的所有绑定都未限定作用域。这意味着,每当应用请求绑定时,Hilt 都会创建所需类型的一个新实例。

不过,Hilt 也允许将绑定的作用域限定为特定组件。Hilt 只为绑定作用域限定到的组件的每个实例创建一次限定作用域的绑定,对该绑定的所有请求共享同一实例。

了解完上面这几个概念之后,我们用一个案例来说明如何使用Hilt。

  1. Hilt的引入
    首先,将 hilt-android-gradle-plugin 插件添加到项目的根级 build.gradle 文件中:
plugins {...id 'com.google.dagger.hilt.android' version '2.44' apply false
}

然后,应用Gradle插件并在app/build。gradle文件中添加下面依赖项:

...
plugins {id 'kotlin-kapt'id 'com.google.dagger.hilt.android'
}android {...
}dependencies {implementation "com.google.dagger:hilt-android:2.44"kapt "com.google.dagger:hilt-compiler:2.44"annotationProcessor "com.google.dagger:hilt-compiler:2.44"}
  1. 新建一个module
package com.example.test;public class Student {}
package com.example.test;import javax.inject.Singleton;import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.components.ActivityComponent;
import dagger.hilt.components.SingletonComponent;// ActivityComponent.class    能注入到Activity,不能注入到Application
// SingletonComponent.class 能注入到Activity, 能注入到Application@Module
@InstallIn(SingletonComponent.class) // 注入到Activity里面去(按规则来,该是哪个注入,就写哪个,不要乱搞)
public class StudentMoudle {// @Singleton // 上面的InstallIn 必须是 (SingletonComponent.class) 才能全局单例@ActivityScoped // 上面的InstallIn 必须是 (ActivityComponent.class) 才能局部单例@Providespublic Student getStudnet(){return new Student();}
}
package com.example.testimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Injectlateinit var stu:Student@Injectlateinit var stu2:Studentoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)Toast.makeText(this,"${stu2.hashCode()}",Toast.LENGTH_LONG).show()Toast.makeText(this,"${stu.hashCode()}",Toast.LENGTH_LONG).show()
//        LogHelper.getInstance().d("MainActivity","Hello World")}
}

与dagger2相比,Hilt不需要在创建component注解了。

接下来,我们就利用Hilt来搭建隔离层框架
首先,我们需要为BLog和XLog类做一些修改

package com.example.test;import android.util.Log;import javax.inject.Inject;public class XLog implements ILogCallback{@Injectpublic XLog(){}@Overridepublic void d(String tag, String msg) {Log.d("XLog"+tag,msg);}@Overridepublic void e(String tag, String msg) {Log.e("XLog"+tag,msg);}
}
package com.example.test;import android.util.Log;import javax.inject.Inject;public class BLog implements ILogCallback{@Injectpublic BLog(){}@Overridepublic void d(String tag, String msg) {Log.d("BLog"+tag,msg);}@Overridepublic void e(String tag, String msg) {Log.e("BLog"+tag,msg);}
}

接着,创建两个注解,我们通过切换不同的注解来更换不同的log

package com.example.test.annotation;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;import javax.inject.Qualifier;@Qualifier // 此注解就是为了让 hilt 区分这个注解(做自己的逻辑处理)  自己定义标识,限定符号
@Retention(RetentionPolicy.RUNTIME)
public @interface BLog {}
package com.example.test.annotation;import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;import javax.inject.Qualifier;@Qualifier // 此注解就是为了让 hilt 区分这个注解(做自己的逻辑处理)  自己定义标识,限定符号
@Retention(RetentionPolicy.RUNTIME)
public @interface XLog {}

最后,新建一个Module,在里面进行绑定

package com.example.test;import javax.inject.Singleton;import dagger.Binds;
import dagger.Module;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;@Module
@InstallIn(SingletonComponent.class)
public abstract class LogInterfaceModule {@com.example.test.annotation.XLog@Binds@Singletonpublic abstract ILogCallback bind(XLog log);@com.example.test.annotation.BLog@Binds@Singletonpublic abstract ILogCallback bindB(com.example.test.BLog log);
}
package com.example.test;import android.app.Application;import com.example.test.annotation.BLog;
import com.example.test.annotation.XLog;import javax.inject.Inject;import dagger.hilt.android.HiltAndroidApp;@HiltAndroidApp
public class MyApplication extends Application {//只需要切换不同的注解便可以切换log@Inject
//    @XLog@BLogpublic ILogCallback logCallback;@Overridepublic void onCreate() {super.onCreate();//        LogHelper.getInstance().init(new XLog());
//        LogHelper.getInstance().init(new BLog());}public ILogCallback getLog(){return logCallback;}
}
package com.example.testimport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Injectlateinit var stu:Student@Injectlateinit var stu2:Studentoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)(application as MyApplication).log.d("xxxx","MainActivity")}}

参考资料

https://developer.android.com/training/dependency-injection/hilt-android#component-hierarchy

使用Hilt搭建隔离层架构相关推荐

  1. CS通用项目系统搭建——三层架构第一天

    CS通用项目:使用三层架构进行搭建 三层架构: 表现层(UI(User Interface)):展示给用户的层面,包含窗体控件数据等信息. 业务逻辑层(BLL(Business Logic Layer ...

  2. 搭建分布式架构4--ZooKeeper注册中心安装

    2019独角兽企业重金招聘Python工程师标准>>> ZooKeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务--分布式同步(Distr ...

  3. 爬虫 spider11——搭建分布式架构通过feign技术,开发服务消费者

    搭建分布式架构,把3中开发的服务提供者,注册到eureka server(三台,7001,7002,7003) 开发服务消费者(可以直接访问3中的服务),调试成功后, 通过feign技术,开发服务消费 ...

  4. 搭建PC架构的ISCSI存储系统

    搭建PC架构的ISCSI存储系统 一.架构图: 需求:把iscsi-target 服务器上的/dev/sdc共享出来,分别从windows和linux客户端来进行挂载使用. iscsi-target服 ...

  5. Centos7 搭建LNMP架构服务器实战

    Centos7 搭建LNMP架构服务器实战 前言 需求分析 拓朴设计及各服务器地址规划 配置部分 后端服务器实现 Web-1 nginx整合 Web-2 nginx整合 后端服务器测试 高可用Web集 ...

  6. CentOS 6.7 源码搭建LNMP架构部署动态网站环境

    源码搭建LNMP架构部署动态网站环境 Nginx 简介 Nginx是一款相当优秀的用于部署动态网站的服务程序,Nginx具有不错的稳定性.丰富的功能以及占用较少的系统资源等独特特性. Nginx (& ...

  7. 从零到一搭建基础架构(2)-如何构建基础架构模块划分

    Hello,这里是爱 Coding,爱 Hiphop,爱喝点小酒的 AKA 柏炎. 本篇是手把手搭建基础架构专栏的第二篇. 在第一篇<从零到一搭建基础架构(1)-玩转maven依赖版本管理> ...

  8. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影系统

    作者:JackTian 微信公众号:杰哥的IT之旅(ID:Jake_Internet) LAMP 系列导读 01. LAMP 系列教程(一)| 详解 Linux 环境下部署 HTTPD 服务 02. ...

  9. 快速搭建LAMP架构

    快速搭建LAMP架构 1.安装apache 2.部署mysql 3.部署php结合apache 4.验证 5.部署一个论坛disuz 1.安装apache [root@localhost ~]# yu ...

最新文章

  1. 关于GCN,我有三种写法
  2. 15.泡菜:pickle模块
  3. Kira同学:斩获百度校招提前批offer备战细节全揭秘
  4. Debian Squeeze AMD64安装Oracle 10g x86_64 10.2.0....
  5. springboot 整合mybatis_SpringBoot整合Mybatis、MybatisPuls
  6. SWIG Python-C封装 char*相关问题(3)
  7. SpringMVC与Struts2关于controller线程安全问题
  8. unity scence灯光不显示_Unity基础教程系列(四)——多场景(Loading Levels)
  9. linux中 查看系统属性 与 可执行文件属性 的方法
  10. python 爬虫 糗百成人
  11. acm 算法 java_有关acm算法的一道java题
  12. Term Weighting
  13. 如何选择适合自己的树莓派产品
  14. Base64与MD5(数据加密)与ValidateCode(验证码)
  15. 《UnityAPI.Component组件》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+GetComponent+SendMessage+Tag+立钻哥哥++OK++)
  16. 22年春晚,一个让元宇宙照进现实的沉浸式演出舞台
  17. Iteratot(迭代器模式) 行为型
  18. 阿里云态势感知以及安骑士分析
  19. Video process: 视频剪辑和格式转换 (windows)
  20. ubuntu18.04配置ORB-SLAM3(包含ROS)完整版教程

热门文章

  1. 赵本山2007春节晚会小品(畅想版)——超级搞笑
  2. 导航软件哪个最好用?这里有3款最流行的导航软件
  3. 激战2游戏未能链接服务器,关于近期服务器故障和活动的一些说明
  4. 关于扼制抑制Win10自动更新,关闭更新方法
  5. 如何用小米手机查看当前移动信号的强弱
  6. python什么元素为真_在Python中“真”用true表示 。
  7. Python类属性与实例变量
  8. 可能是最全面的国内外知名404页面盘点
  9. 第八期 RT3052F芯片分析 《路由器就是开发板》
  10. charles抓包-手机