Android技术栈(三)依赖注入技术的探讨与实现

本文介绍了Liteproj框架如何通过工厂和Builder模式创建对象,强调对象所有权在Android开发中的重要性,并详细阐述了其与Activity、Service、ViewModel的生命周期绑定。文章还讨论了依赖注入的隐式装配和与Dagger和Spring的区别,以及如何发布到jitpack.io。尽管存在一些缺点,如依赖纯反射和XML解析,但Liteproj提供了一种简洁的解决方案,适用于快速开发和轻量级项目。
摘要由CSDN通过智能技术生成

@Override
public String toString()
{
return super.toString() + “\n” + field + “\n” + object + “\n” + string;
}
}

  • 使用JavaBean

代码还是上面的代码,只不过这次加了点东西,factory,builder,new定义了对象的构造方式,我们还可以用fieldproperty标签在对象生成后为对象赋值,通过name属性指定要赋值给哪个字段或属性,property所指定的name应该是一个方法,它的命名应该符合Javasetter标准,比如name="abc",对应void setAbc(YourType)方法








  • val转换为var

我知道每次重复写字面值很蠢,所以提供了val转换为var的方法,让字面值可以像var一样被ref使用

复制代码
  • 完整的xml

最后在这里提一点无论是factory还是builder都不允许返回null值,默认导入的null只是为了兼容某些特殊情况而设计的,factorybuilder返回null是没有意义的.

<?xml version="1.0" encoding="utf-8"?>

6.生命周期和对象所有权

如果说Android开发中影响范围最广泛的概念是什么,我想那一定就是生命周期了。

因为你会发现几乎什么东西都能跟生命周期扯上关系,在组件创建的时候订阅或请求数据,并一定要记得在组件销毁的时候取消订阅和清理数据,要不然你就等着内存泄漏和迷之报错吧。

还有一个和生命周期有关联的词,那就是对象所有权.

如果Activity或者Service引用了Application的资源,这很合理,因为Application的生命周期比Activity要长,不必担心内存泄漏,但如果Application引用了Activity的资源,这就有点不合理了,因为Activity可能随时被杀掉,而Application的生命周期又比Activity长,这就容易造成本该在Activity中释放的资源一直被Application持有,进而造成内存泄漏,所以Application不应该有Activity或者Service上资源的对象所有权。

所以Liteproj从一开始就设计成和组件的生命周期绑定在一起,并制定了合理的对象所有权。

Liteproj支持对5组件进行依赖注入:

  • Application,无特殊要求,会在attachBaseContext之后与onCreate之前执行依赖注入
  • Activity,至少是FragmentActivity(AppCompatActivity继承了FragmentActivity)
  • Service,需要继承Liteprojorg.kexie.android.liteproj.LiteService
  • Fragment,继承appcompatFragment即可
  • ViewModel,需要继承Liteprojorg.kexie.android.liteproj.LiteViewModel

可以看到Liteproj的倾入性还是很低的,除了ServiceViewModel需要强制继承基类,其他组件的基本上都无需代码改动.

图是用ProcessOn画的:

image.png

ServiceActivity可以使用Applicationxml配置文件,因为Application的生命周期比ServiceActivity都长,同理Fragment可以使用Activityxml配置文件,而ViewModel由于不能违背MVVM的设计原则(ViewModel不应该知道他是与哪一个View进行交互的),所以除了自己能使用自己的xml配置文件之外只允许它使用Applicationxml配置文件.

Liteproj中各种组件的依赖都由DependencyManager进行管理,可以通过DependencyManager.from(owner)获得该实例的DependencyManager.

可以通过DependencyManager#get(String name)主动获取xml中定义的依赖,也可以使用隐式装配(下面马上介绍).

当一个依赖的名字在本组件的DependencyManager找不到的时候,DependencyManager就会把请求转发到上层的DependencyManager中,比如在Activity中找不到某个依赖时,就跑到Application上去找(但前提是你的Activity@Using注解中引用了Application的依赖配置文件).

DependencyManager与组件的生命周期绑定,在组件生命周期结束时,会释放自己占有的所有资源.

7.隐式装配

在继续对比DaggerSpring两者依赖注入的行为中,我发现Spring有一个Dagger没有的优点,那就是在依赖注入中的一个设计原则,即一个对象不应该知道自己的依赖是何时怎样被注入的。

为了实现这个功能,我编写了一个ContentProvider作为框架的初始化器(仿照Android Jetpack Lifecycle包的做法),ContentProvider可以在ApplicationattachBaseContext之后与onCreate之前对框架进行初始化,并对Application进行依赖注入,自此,Liteproj终于大功告成.

现在,你只需要使用@Reference注解,然后填入名字就可以就可以给自己的组件进行依赖注入了,@Reference注解与xml中的ref作用基本一致,但是你将value留空的时候,它可以使用属性名或字段名进行自动装配.

@Retention(RUNTIME)
@Target({FIELD, METHOD})
public @interface Reference
{
String value() default “”;
}

就好比这样(所有代码都来自GithubDemo中):

@Using({R.xml.all_test})
public class MainActivity extends AppCompatActivity
{
private static final String TAG = “MainActivity”;

@Reference(“request”)
Request request;

@Reference(“bean”)
Bean bean;

@Reference(“holder”)
AppHolderTest holderTest;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.d(request + “\n” + bean + “\n” + holderTest.context);
}
}

直接运行你的APP,就可以看到这些对象居然都被自动设置好了,对的,不需要自定义的Application类,也不需要你去调用奇怪的init方法再传入一个Context实例.

JSR-330相比,Liteproj只有@Using@Reference这两个注解,这样是不是简单多了?

8.发布到jitpack.io

一切代码都编写完成后最后一步当然就是把它发布到在线的maven仓库了,这里我选择了jitpack.io,因为它实在是太方便了有木有,它与Github高度集成,发布一个自己的类库甚至都不需要你登录账号.

image.png

在根项目的build.gradle中添加

buildscript {

repositories {
google()
jcenter()
}
dependencies {
classpath ‘com.android.tools.build:gradle:3.2.0’
// ↓↓↓↓↓↓↓↓↓↓↓↓ 加这行! 加这行! ↓↓↓↓↓↓↓↓↓↓↓↓
classpath ‘com.github.dcendents:android-maven-gradle-plugin:2.1’

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

然后继续在你要发布的模块的build.gradle的头部添加

apply plugin: ‘com.android.library’
//↓↓↓↓↓↓↓↓↓↓↓↓ 加这行! 加这行! ↓↓↓↓↓↓↓↓↓↓↓↓
apply plugin: ‘com.github.dcendents.android-maven’
//↓↓↓↓↓↓↓↓↓↓↓↓ 加这行! 加这行!并且group改成你想要的 ↓↓↓↓↓↓↓↓↓↓↓↓
group=‘org.kexie.android’

然后Look up

image.png

log中查看编译log,点击get it即可开始在jitpack上编译你的项目image.png

如果成功

allprojects {
repositories {

maven { url ‘https://www.jitpack.io’ }
}
}
dependencies {
implementation ‘com.github.LukeXeon:Liteproj:+’
}

你就可以用gradle远程依赖了.

如果失败,你就得注意一下classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'这个插件了,不同的gradle版本有对应不同的插件版本,笔者的gradle4.10.1,具体版本对应可以在这里查看.

9.Liteproj的缺点

我每次写文章,我总会在写便了xxx的好处后的倒数第二个标题总结xxx的缺点,当然我也不会放过我自己写的库。(我认真起来连我自己都盘,盘我!)

如你所见Liteproj还是一个很年轻的依赖注入框架,如果你要将它用到商业项目中,可能需要辛苦你测试一下它有没有一些坑之类的(逃…不过好在咱是开源的对吧,代码其实也就1-2k也不多)。

其次,Liteproj没有使用注解处理器来在编译时处理注解,而是依赖纯反射,而且它还需要解析xml,虽然只会解析一次,之后xml文件中的依赖信息就会转换为内存中的数据结构,下次再使用这个xml配置文件就是直接使用内存中已经加载好的数据了,且在xml解析时也使用了多线程来进行优化,尽最大的可能减少了主线程的等待时间,但这依然可能会带来一些微小的效率问题。

10.结语

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

我这里整理了一份完整的学习思维以及Android开发知识大全PDF,有需要的同学可以自行领取。

资料获取方式:Android完整知识学习体系路线

当然实践出真知,即使有了学习线路也要注重实践,学习过的内容只有结合实操才算是真正的掌握。

链图片转存中…(img-qrNCntqc-1710823774456)]

最后

我这里整理了一份完整的学习思维以及Android开发知识大全PDF,有需要的同学可以自行领取。

[外链图片转存中…(img-EfYTC62d-1710823774456)]

资料获取方式:Android完整知识学习体系路线

当然实践出真知,即使有了学习线路也要注重实践,学习过的内容只有结合实操才算是真正的掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值