imtoken苹果官方下载|dagger

作者: imtoken苹果官方下载
2024-03-07 18:04:21

DAGGER中文(简体)翻译:剑桥词典

DAGGER中文(简体)翻译:剑桥词典

词典

翻译

语法

同义词词典

+Plus

剑桥词典+Plus

Shop

剑桥词典+Plus

我的主页

+Plus 帮助

退出

剑桥词典+Plus

我的主页

+Plus 帮助

退出

登录

/

注册

中文 (简体)

查找

查找

英语-中文(简体)

dagger 在英语-中文(简体)词典中的翻译

daggernoun [ C ] uk

Your browser doesn't support HTML5 audio

/ˈdæɡ.ər/ us

Your browser doesn't support HTML5 audio

/ˈdæɡ.ɚ/

Add to word list

Add to word list

a short, pointed knife that is sharp on both sides, used especially in the past as a weapon

(尤指旧时的)匕首,短剑

习语

(at) daggers drawn

(dagger在剑桥英语-中文(简体)词典的翻译 © Cambridge University Press)

A1

dagger的翻译

中文(繁体)

(尤指舊時的)匕首,短劍…

查看更多内容

西班牙语

daga, puñal…

查看更多内容

葡萄牙语

punhal, adaga…

查看更多内容

更多语言

日语

土耳其语

法语

加泰罗尼亚语

in Dutch

阿拉伯语

捷克语

丹麦语

印尼语

泰语

越南语

波兰语

in Swedish

马来语

德语

挪威语

韩语

in Ukrainian

意大利语

俄语

短刀…

查看更多内容

silah olarak da kullanılabilen, kama, kısa bıçak…

查看更多内容

poignard…

查看更多内容

punyal, daga…

查看更多内容

dolk…

查看更多内容

خَنْجَر…

查看更多内容

dýka…

查看更多内容

dolk, daggert…

查看更多内容

belati…

查看更多内容

กริช…

查看更多内容

dao găm…

查看更多内容

sztylet…

查看更多内容

dolk…

查看更多内容

pisau belati…

查看更多内容

der Dolch…

查看更多内容

dolk, daggert…

查看更多内容

단도…

查看更多内容

кинджал…

查看更多内容

pugnale…

查看更多内容

кинжал…

查看更多内容

需要一个翻译器吗?

获得快速、免费的翻译!

翻译器工具

dagger的发音是什么?

在英语词典中查看 dagger 的释义

浏览

daffodil

daffy

daft

dag

dagger

daggy

dagnabbit

dago

daguerreotype

dagger更多的中文(简体)翻译

全部

cloak-and-dagger

查看全部意思»

“每日一词”

veggie burger

UK

Your browser doesn't support HTML5 audio

/ˈvedʒ.i ˌbɜː.ɡər/

US

Your browser doesn't support HTML5 audio

/ˈvedʒ.i ˌbɝː.ɡɚ/

a type of food similar to a hamburger but made without meat, by pressing together small pieces of vegetables, seeds, etc. into a flat, round shape

关于这个

博客

Forget doing it or forget to do it? Avoiding common mistakes with verb patterns (2)

March 06, 2024

查看更多

新词

stochastic parrot

March 04, 2024

查看更多

已添加至 list

回到页面顶端

内容

英语-中文(简体)翻译

©剑桥大学出版社与评估2024

学习

学习

学习

新词

帮助

纸质书出版

Word of the Year 2021

Word of the Year 2022

Word of the Year 2023

开发

开发

开发

词典API

双击查看

搜索Widgets

执照数据

关于

关于

关于

无障碍阅读

剑桥英语教学

剑桥大学出版社与评估

授权管理

Cookies与隐私保护

语料库

使用条款

京ICP备14002226号-2

©剑桥大学出版社与评估2024

剑桥词典+Plus

我的主页

+Plus 帮助

退出

词典

定义

清晰解释自然的书面和口头英语

英语

学习词典

基础英式英语

基础美式英语

翻译

点击箭头改变翻译方向。

双语词典

英语-中文(简体)

Chinese (Simplified)–English

英语-中文(繁体)

Chinese (Traditional)–English

英语-荷兰语

荷兰语-英语

英语-法语

法语-英语

英语-德语

德语-英语

英语-印尼语

印尼语-英语

英语-意大利语

意大利语-英语

英语-日语

日语-英语

英语-挪威语

挪威语-英语

英语-波兰语

波兰语-英语

英语-葡萄牙语

葡萄牙语-英语

英语-西班牙语

西班牙语-英语

English–Swedish

Swedish–English

半双语词典

英语-阿拉伯语

英语-孟加拉语

英语-加泰罗尼亚语

英语-捷克语

英语-丹麦语

English–Gujarati

英语-印地语

英语-韩语

英语-马来语

英语-马拉地语

英语-俄语

English–Tamil

English–Telugu

英语-泰语

英语-土耳其语

英语-乌克兰语

English–Urdu

英语-越南语

翻译

语法

同义词词典

Pronunciation

剑桥词典+Plus

Shop

剑桥词典+Plus

我的主页

+Plus 帮助

退出

登录 /

注册

中文 (简体)  

Change

English (UK)

English (US)

Español

Русский

Português

Deutsch

Français

Italiano

中文 (简体)

正體中文 (繁體)

Polski

한국어

Türkçe

日本語

Tiếng Việt

हिंदी

தமிழ்

తెలుగు

关注我们

选择一本词典

最近的词和建议

定义

清晰解释自然的书面和口头英语

英语

学习词典

基础英式英语

基础美式英语

语法与同义词词典

对自然书面和口头英语用法的解释

英语语法

同义词词典

Pronunciation

British and American pronunciations with audio

English Pronunciation

翻译

点击箭头改变翻译方向。

双语词典

英语-中文(简体)

Chinese (Simplified)–English

英语-中文(繁体)

Chinese (Traditional)–English

英语-荷兰语

荷兰语-英语

英语-法语

法语-英语

英语-德语

德语-英语

英语-印尼语

印尼语-英语

英语-意大利语

意大利语-英语

英语-日语

日语-英语

英语-挪威语

挪威语-英语

英语-波兰语

波兰语-英语

英语-葡萄牙语

葡萄牙语-英语

英语-西班牙语

西班牙语-英语

English–Swedish

Swedish–English

半双语词典

英语-阿拉伯语

英语-孟加拉语

英语-加泰罗尼亚语

英语-捷克语

英语-丹麦语

English–Gujarati

英语-印地语

英语-韩语

英语-马来语

英语-马拉地语

英语-俄语

English–Tamil

English–Telugu

英语-泰语

英语-土耳其语

英语-乌克兰语

English–Urdu

英语-越南语

词典+Plus

词汇表

选择语言

中文 (简体)  

English (UK)

English (US)

Español

Русский

Português

Deutsch

Français

Italiano

正體中文 (繁體)

Polski

한국어

Türkçe

日本語

Tiếng Việt

हिंदी

தமிழ்

తెలుగు

内容

英语-中文(简体) 

 Noun

Translations

语法

所有翻译

我的词汇表

把dagger添加到下面的一个词汇表中,或者创建一个新词汇表。

更多词汇表

前往词汇表

对该例句有想法吗?

例句中的单词与输入词条不匹配。

该例句含有令人反感的内容。

取消

提交

例句中的单词与输入词条不匹配。

该例句含有令人反感的内容。

取消

提交

从 Dagger 到 Hilt,谷歌为何执着于让我们用依赖注入? - 知乎

从 Dagger 到 Hilt,谷歌为何执着于让我们用依赖注入? - 知乎首发于HenCoder切换模式写文章登录/注册从 Dagger 到 Hilt,谷歌为何执着于让我们用依赖注入?扔物线​Android 开发话题下的优秀答主视频先行 开始 说到依赖注入,做 Android 的人都会想到一个库:Dagger;说到 Dagger,大家的反应普遍是一套三连:牛逼、高端、我才不用。又牛逼又高端,为什么不用?因为太难了。是吧?又难学又难用。大多数的人在学习 Dagger 的路上就被直接劝退了,剩下的这一小撮人最终排除万难,学会并且用上了 Dagger,但多半都是用着用着就掉进了自己亲手用 Dagger 搭建的迷宫里,怎么也绕不清楚,而且越陷越深,就这么成年累月地被它折磨。有人可能会说:难用就别用呗?拆出来啊。拆?哼哼。你对 Dagger 一无所知。而就在上个月,Android 团队又在 Jetpack 里面又增加了一个新的依赖注入库:Hilt。这个 Hilt 是专门针对于 Android 平台的依赖注入库,它是基于 Dagger 的。 啊?基于……Dagger?这次到底是真正的神器到来,还是又一个大坑? 依赖注入是什么 Dagger 的名字取自有向无环图 DAG (directed acyclic graph):因为程序里的依赖关系拼接起来就是一个或者多个有向无环图:DAG-er,Dagger,取了个谐音,Dagger 是匕首的意思。而这次的 Hilt 是刀柄的意思,匕首很难用是吧?来,给你个柄。说得很好听,到底有没有那么好用啊?这是个复杂的问题,且听我慢慢道来~依赖注入有什么用 Hilt 好不好用,我们先来看看它是个什么。它是个用注解来进行配置的依赖注入库。注解是它的写法,首先它是个依赖注入库,对吧?什么是依赖注入?一个类里有两个变量,这两个变量就是它的依赖:要初始化一个依赖,有两种方法:第一,你这个类自己初始化:第二,让外部帮你初始化。其中这第二种,让外部帮你初始化你的依赖,就叫依赖注入。关键在于初始化是谁做的,至于最后一步是你把结果拿过来,还是说你连拿都不用拿,最后一步的赋值工作也让外部来帮你做了,这都不重要,只要初始化工作是外部做的,就都叫依赖注入。所以 Factory 的使用是依赖注入吗?是的。Builder?也是。带参数的构造函数?也是!这些都属于由外部来提供依赖的初始化,所以都是依赖注入,并不是非要像 Dagger 那样使用注解的像魔法一样的才叫依赖注入。也就是说,其实我们每个人都已经在使用依赖注入了。虽然很多人在面对 Dagger 的时候会问「依赖注入到底有什么用」,但其实 Dagger 并不是提供了依赖注入的能力,而是为依赖注入提供了一种更简单的方式。依赖注入本来就是有用的,这个问题不想明白,不管是 Dagger 还是现在的 Hilt,你都用不好。Dagger 让我们可以用注解的方式来配置依赖关系,让依赖注入变得更方便。不过由于功能复杂,导致它的上手非常困难;再加上刚才我说的,很多人对于依赖注入的作用以及 Dagger 的定位都没搞清楚,这两个原因加起来,就导致很多人还没学会 Dagger 就把它弃了,让 Dagger 成为 Android 史上最受冷落的优质库。这样的结果不论是对 Dagger 还是对我们,都是很可惜的。而 Hilt 的出现,就直接解决了 Dagger 太复杂的这个问题。Hilt 怎么帮助我们进行依赖注入 Hilt 是 Google 专门针对 Android 平台做的一个依赖注入库。它不是从里到外全新开发的,而是基于 Dagger 做的,它的下层还是 Dagger。为什么不直接去优化改进 Dagger,而要基于它做一个新库呢?因为 Hilt 做的事其实也并不是对 Dagger 进行优化,而是场景化:针对 Android 开发制定了一系列的规则,通过这些规则大大简化了这套工具的使用。例如在 Dagger 里,你要对某个类的依赖进行注入,你需要手动获取依赖图和执行注入依赖操作:而在 Hilt 里,注入会自动完成:因为 Hilt 会自动找到 Android 的系统组件里面那些最佳的初始化位置——比如 Activity 的 onCreate() ——然后在这些位置注入依赖。所以,为什么不是去优化 Dagger,而是做了个新库?因为 Hilt 本身并不是一种优化,而是场景化,或者说,它是一种针对场景的优化。总之,它是不通用的,只能给 Android 用,所以不能放在 Dagger 里。有点明白了吧?那它具体怎么用呢?大概是这样的:我们程序里有些对象是全局共享的,比如线程池,或者 Retrofit 对象,这种东西我们通常会把它放在 Application 对象里,或者做成单例的:而如果用 Hilt,你也可以把它做成自动注入的依赖:还有些对象是局部共享的,比如某个 Activity 会把一些显示用的数据共享给它内部的一些 View 和 Fragment。这一类情况我们的做法通常是获取外部 Activity 对象然后强转,再去拿它内部的对象:而如果用 Hilt,你可以把这个对象直接声明出来,让它自动注入:这不只是一个「美观」的差别,依赖注入可以让你的程序更加灵活,比如如果你的 View 可以在多个不同的 Activity 里显示,那你在 View 里面要怎么强转?你要转成谁?很麻烦,是吧?而如果用依赖注入,这些就都是自动的。除了共享的对象,不共享的也可以用依赖注入的方式来进行初始化,因为依赖注入的作用除了对共享对象提供一致性支持,也可以让我们在创建任何对象的时候省一些思考和力气:@Inject newUser: User

总之,如果一个组件可能会被被共享,或者不会被共享但可能会在多处使用,你都可以使用 Hilt 来把它配置成依赖注入的加载方式。加载的方式可以选择直接调用构造函数:或者指定子类或实现类:或者干脆给出具体的代码:加载的作用域可以选择默认的每次都初始化,也可以设置成全局单例的:也可以设置成针对任何 Activity、Fragment、View 或者 ViewModel 的局部共享:简单又强大,好用又灵活。具体的写法你可以去看文档,或者过段时间我会有一次公开课,到时候也会提前通知大家。到这里有的人可能会分个叉可能会想:诶 ButterKnife 或者现在 Jetpack 推出的 ViewBinding 它们提供的功能,Hilt 提供了吗?因为如果提供了,我在用了 Hilt 之后,不就可以把 ButterKnife 和 ViewBinding 扔掉了?不好意思,Hilt 不提供它们的功能。Hilt 和 Dagger 虽然用法和 ButterKnife 很像,都是给变量加注解,然后变量会自动赋值,但它们的功能定位是不一样的:Hilt 和 Dagger 是做依赖注入的,而 ButterKnife 和 ViewBinding 是做视图绑定的。这可不是个文字游戏,依赖注入和视图绑定是有本质区别的:依赖注入是由外部对对象进行初始化,也就是所谓的控制翻转;而视图绑定是让变量去指向一个已经有了的 View,它的依赖依然是由依赖持有者自己决定的,这是一个本质的区别。更多它们的区别我就不细讲了,想了解的话,给你推荐个东西:在这个世界上有一个人叫扔物线,他出了一套 Android 高级进阶系列化课程,这套课程涵盖了中高级 Android 工程师进阶提升需要的方方面面,其中依赖注入和视图绑定的区别——只是冰山一角。而你只需要做一件事:报名,买它。学完这套课,你会收获技术和薪资的双重提升——当然你得好好学啊,我的课含金量比较高,刷起来可能有点慢,但是只要认真刷完,你就不再是你了。快扫扫码呀!(恰自己家的饭,真香)https://qrcode.hencoder.com (二维码自动识别)Dagger 为什么难用 这么看来,Hilt 还是很好用的,是吧?那有些人就又有问题了:哎,Hilt 这么好用,那Dagger 真的难用吗?到底难用在哪了?其实说白了,Dagger 的难用主要在于这个框架太强大和灵活了,导致你要遵守很多约定才能正确使用它。比如在 Hilt 里,一个注解就能让 Activity 内部的依赖自动被注入,而 Dagger 需要手动注入;再比如在 Hilt 里如果你想让一个对象只在 Activity 内部被共享而不是全局共享,也就是一个注解能解决的问题,而在 Dagger 里面你需要先去创建一个自定义的注解。这些难吗?每个都不难的,对吧?但把它们放在一起,让你灵活搭配使用,就有点难了。另外,Dagger 被大家普遍认为难的另一个原因刚才我也说过了:很多人连依赖注入都不太懂的。所以我再说一遍:如果一个组件可能被共享,或者可能在多处被使用,你可以使用依赖注入来初始化它。然后,在需要依赖注入的场景里,使用 Dagger 能让你的依赖注入写起来更简单。最后,Hilt 进一步简化了这个事情。先知道它是什么,再去用它。其实我在我的知识星球里也分享了依赖注入的使用原则(球友们没看的快去看看):你如果是一个追求技术的 Android 工程师,非常推荐加入我的星球,我在这里会对于各种好的、新的、难的技术给出技术分享和我的个人见解,微软中国的 Android 工程师 Drakeet 许晓锋也在这里和我一起分享知识和经验:以及,你在我的视频和公开课里看到的东西也可以在星球讨论和问我。总结 啊我收!所以今天表面上是在介绍 Hilt,其实是对于 Hilt 以及它背后的依赖注入机制进行一个整体的讲解,希望对你可以有帮助。大家学知识和技术的时候,一定不要只关注表面,要透过表面看到里面的本质,掌握最核心的东西。那么回到这期的标题——《从 Dagger 到 Hilt,谷歌为何执着于让我们用依赖注入》,为什么?其实谷歌并没有非要让我们使用依赖注入,而是我们本来就需要使用依赖注入,谷歌只是想提供一种更方便的方式让我们去使用依赖注入而已。Dagger 很强大,但太难学从而导致太难用;而 Hilt 彻底扫除了这个障碍,那……要不咱给它个机会?本文使用 mdnice 排版发布于 2020-07-29 18:07Android 开发KotlinHilt​赞同 34​​4 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录HenCoder给高级 Android 工程师的进

DAGGER中文(繁體)翻譯:劍橋詞典

DAGGER中文(繁體)翻譯:劍橋詞典

詞典

翻譯

文法

同義詞詞典

+Plus

劍橋詞典+Plus

Shop

劍橋詞典+Plus

我的主頁

+Plus 幫助

退出

劍橋詞典+Plus

我的主頁

+Plus 幫助

退出

登錄

/

註冊

正體中文 (繁體)

查找

查找

英語-中文(繁體)

dagger 在英語-中文(繁體)詞典中的翻譯

daggernoun [ C ] uk

Your browser doesn't support HTML5 audio

/ˈdæɡ.ər/ us

Your browser doesn't support HTML5 audio

/ˈdæɡ.ɚ/

Add to word list

Add to word list

a short, pointed knife that is sharp on both sides, used especially in the past as a weapon

(尤指舊時的)匕首,短劍

習語

(at) daggers drawn

(dagger在劍橋英語-中文(繁體)詞典的翻譯 © Cambridge University Press)

A1

dagger的翻譯

中文(簡體)

(尤指旧时的)匕首,短剑…

查看更多內容

西班牙語

daga, puñal…

查看更多內容

葡萄牙語

punhal, adaga…

查看更多內容

更多語言

日語

土耳其語

法語

加泰羅尼亞語

in Dutch

阿拉伯語

捷克語

丹麥語

印尼語

泰語

越南語

波蘭語

in Swedish

馬來西亞語

德語

挪威語

韓語

in Ukrainian

意大利語

俄語

短刀…

查看更多內容

silah olarak da kullanılabilen, kama, kısa bıçak…

查看更多內容

poignard…

查看更多內容

punyal, daga…

查看更多內容

dolk…

查看更多內容

خَنْجَر…

查看更多內容

dýka…

查看更多內容

dolk, daggert…

查看更多內容

belati…

查看更多內容

กริช…

查看更多內容

dao găm…

查看更多內容

sztylet…

查看更多內容

dolk…

查看更多內容

pisau belati…

查看更多內容

der Dolch…

查看更多內容

dolk, daggert…

查看更多內容

단도…

查看更多內容

кинджал…

查看更多內容

pugnale…

查看更多內容

кинжал…

查看更多內容

需要一個翻譯器嗎?

獲得快速、免費的翻譯!

翻譯器工具

dagger的發音是什麼?

在英語詞典中查看 dagger 的釋義

瀏覽

daffodil

daffy

daft

dag

dagger

daggy

dagnabbit

dago

daguerreotype

dagger更多的中文(繁體)翻譯

全部

cloak-and-dagger

查看全部意思»

「每日一詞」

veggie burger

UK

Your browser doesn't support HTML5 audio

/ˈvedʒ.i ˌbɜː.ɡər/

US

Your browser doesn't support HTML5 audio

/ˈvedʒ.i ˌbɝː.ɡɚ/

a type of food similar to a hamburger but made without meat, by pressing together small pieces of vegetables, seeds, etc. into a flat, round shape

關於這個

部落格

Forget doing it or forget to do it? Avoiding common mistakes with verb patterns (2)

March 06, 2024

查看更多

新詞

stochastic parrot

March 04, 2024

查看更多

已添加至 list

回到頁面頂端

內容

英語-中文(繁體)翻譯

©劍橋大學出版社與評估2024

學習

學習

學習

新詞

幫助

紙本出版

Word of the Year 2021

Word of the Year 2022

Word of the Year 2023

開發

開發

開發

詞典API

連按兩下查看

搜尋Widgets

執照資料

關於

關於

關於

無障礙閱讀

劍橋英語教學

劍橋大學出版社與評估

授權管理

Cookies與隱私保護

語料庫

使用條款

京ICP备14002226号-2

©劍橋大學出版社與評估2024

劍橋詞典+Plus

我的主頁

+Plus 幫助

退出

詞典

定義

清晰解釋自然的書面和口頭英語

英語

學習詞典

基礎英式英語

基礎美式英語

翻譯

點選箭頭改變翻譯方向。

雙語詞典

英語-中文(簡體)

Chinese (Simplified)–English

英語-中文(繁體)

Chinese (Traditional)–English

英語-荷蘭文

荷蘭語-英語

英語-法語

法語-英語

英語-德語

德語-英語

英語-印尼語

印尼語-英語

英語-義大利語

義大利語-英語

英語-日語

日語-英語

英語-挪威語

挪威語-英語

英語-波蘭語

波蘭語-英語

英語-葡萄牙語

葡萄牙語-英語

英語-西班牙語

西班牙語-英語

English–Swedish

Swedish–English

半雙語詞典

英語-阿拉伯語

英語-孟加拉文

英語-加泰羅尼亞語

英語-捷克語

英語-丹麥語

English–Gujarati

英語-印地語

英語-韓語

英語-馬來語

英語-馬拉地語

英語-俄語

English–Tamil

English–Telugu

英語-泰語

英語-土耳其語

英語-烏克蘭文

English–Urdu

英語-越南語

翻譯

文法

同義詞詞典

Pronunciation

劍橋詞典+Plus

Shop

劍橋詞典+Plus

我的主頁

+Plus 幫助

退出

登錄 /

註冊

正體中文 (繁體)  

Change

English (UK)

English (US)

Español

Русский

Português

Deutsch

Français

Italiano

中文 (简体)

正體中文 (繁體)

Polski

한국어

Türkçe

日本語

Tiếng Việt

हिंदी

தமிழ்

తెలుగు

關注我們!

選擇一本詞典

最近的詞和建議

定義

清晰解釋自然的書面和口頭英語

英語

學習詞典

基礎英式英語

基礎美式英語

文法與同義詞詞典

對自然書面和口頭英語用法的解釋

英語文法

同義詞詞典

Pronunciation

British and American pronunciations with audio

English Pronunciation

翻譯

點選箭頭改變翻譯方向。

雙語詞典

英語-中文(簡體)

Chinese (Simplified)–English

英語-中文(繁體)

Chinese (Traditional)–English

英語-荷蘭文

荷蘭語-英語

英語-法語

法語-英語

英語-德語

德語-英語

英語-印尼語

印尼語-英語

英語-義大利語

義大利語-英語

英語-日語

日語-英語

英語-挪威語

挪威語-英語

英語-波蘭語

波蘭語-英語

英語-葡萄牙語

葡萄牙語-英語

英語-西班牙語

西班牙語-英語

English–Swedish

Swedish–English

半雙語詞典

英語-阿拉伯語

英語-孟加拉文

英語-加泰羅尼亞語

英語-捷克語

英語-丹麥語

English–Gujarati

英語-印地語

英語-韓語

英語-馬來語

英語-馬拉地語

英語-俄語

English–Tamil

English–Telugu

英語-泰語

英語-土耳其語

英語-烏克蘭文

English–Urdu

英語-越南語

詞典+Plus

詞彙表

選擇語言

正體中文 (繁體)  

English (UK)

English (US)

Español

Русский

Português

Deutsch

Français

Italiano

中文 (简体)

Polski

한국어

Türkçe

日本語

Tiếng Việt

हिंदी

தமிழ்

తెలుగు

內容

英語-中文(繁體) 

 Noun

Translations

文法

所有翻譯

我的詞彙表

把dagger添加到下面的一個詞彙表中,或者創建一個新詞彙表。

更多詞彙表

前往詞彙表

對該例句有想法嗎?

例句中的單詞與輸入詞條不匹配。

該例句含有令人反感的內容。

取消

提交

例句中的單詞與輸入詞條不匹配。

該例句含有令人反感的內容。

取消

提交

Dagger 2入门 - 知乎

Dagger 2入门 - 知乎切换模式写文章登录/注册Dagger 2入门林林发拒绝平庸Dagger 2是一个依赖注入框架,它成为Android中实现依赖注入的事实标准。由于最初的Dagger 1框架已经过时(据我所知),Dagger 2被广泛称为Dagger。 因此,每当你今天看到Dagger时,你可以放心地认为它指的是Dagger 2.我将在本文中互换使用Dagger和Dagger 2。Dagger最初由Square创建,现在由Google维护。在这篇文章中,我将向您展示如何使用Dagger 2在Android中实现基本的依赖注入。依赖注入软件开发人员和Android开发人员之间的一个常见误解是依赖注入框架是依赖注入的同义词。这远非正确。依赖注入框架只是帮助实现依赖注入体系结构模式的工具。Dagger也不例外。在过去几年中,我向许多Android开发人员解释了依赖注入。根据我的经验,在了解依赖注入框架的具体细节之前了解依赖注入的开发人员可以获得更深入的见解并更快地学习。因此,我强烈建议您在继续本教程之前阅读有关Android中的依赖注入的帖子。本文一般性地讨论了依赖注入体系结构模式,并列出了在Android中实现依赖注入时应遵循的最佳实践。对于本文的其余部分,我将假设您阅读上述文章并理解从那里借用的术语。Gradle设置要在Android项目中使用Dagger 2,我需要在模块的build.gradle文件中添加以下依赖项:dependencies {

...

implementation 'com.google.dagger:dagger:2.14.1'

annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'

...

}进行此修改后,Android Studio将显示一个建议同步项目的弹出窗口。 继续,点击“立即同步”。使用Dagger 2的依赖注入要使用Dagger将服务注入客户端,必须满足三个条件:客户端必须把需要注入的字段设置为protected或者public。必须使用@Inject注释注释该字段。必须调用正确配置的Dagger 2组件的方法注入(客户端),并将客户端的引用作为其参数。例如,如果MyApplication是客户端而SettingsManager是注入的服务,它可能看起来类似于:public class MyApplication extends Application {

@Inject SettingsManager mSettingsManager; // injectable field

private ApplicationComponent mApplicationComponent;

@Override

public void onCreate() {

getApplicationComponent().inject(this); // ApplicationComponent injects into "this" client

mSettingsManager.doSomething();

}

public ApplicationComponent getApplicationComponent() {

if (mApplicationComponent == null) {

mApplicationComponent = DaggerApplicationComponent.builder()

.applicationModule(new ApplicationModule(this))

.build();

}

return mApplicationComponent;

}

}上面列表中的条件1和2应该易于理解。字段必须是protected或public,因为Dagger 2不使用运行时反射并且不能注入私有字段。必须添加@Inject注释,因为Dagger的预处理器会搜索这些注释,以便找到必须注入的字段。另一方面,条件3并不那么简单。“组件”的概念是新的,来自Dagger 2本身。此外,可能不清楚“正确配置”在“组件”的上下文中意味着什么。如果您在阅读本文结尾后查看此条件,您会注意到,实质上,此条件等同于根据Dagger 2提供的模板正确实施构造集。值得注意的是,条件1和2很简单,适用于功能集,而条件3很复杂,适用于构造集。这是分离关注原则的另一种表现形式 - 框架“指导”我们从功能集中删除“构造”逻辑。本文的其余部分讨论了在Android中使用Dagger进行依赖注入时必须满足的最后一个复杂条件。实现构造集与许多其他依赖注入框架一样,Dagger 2提供了一个“模板”,使构造集的实现更容易。 这个模板要求我们使用三种类来实现构造集:ModuleComponentComponent用法让我们分别回顾每种类型。ModuleDagger 2上下文中的Module是一个解决服务之间的依赖关系并实例化它们的类。 您将声明Dagger应该了解哪些服务以及它们在一个或多个模块中的关系。如果您熟悉术语“对象图”,则Module会封装对象图的声明。为了让Dagger 2将类识别为Module,应使用@Module注释进行注释。将SharedPreferences对象声明为可注入服务的模块示例:@Module

public class ApplicationModule {

private final Application mApplication;

public ApplicationModule(Application application) {

mApplication = application;

}

@Provides

SharedPreferences provideSharedPreferences() {

return mApplication.getSharedPreferences(Constants.PREFERENCES_FILE, Context.MODE_PRIVATE);

}

}请注意以下事项:Module只是一个用@Module注释注释的常规类。Module可以选择接受构造函数参数。 这些参数是模块中声明的其他服务的“引导”依赖关系。 Context及其子类是Module构造函数参数的最常见类型。每个可注入服务由一个模块的方法返回,该方法使用@Provides注释进行注释。 这种“提供者”方法名并不重要。ApplicationModule的当前实现仅提供SharedPreferences。 如果我们需要这个模块来提供依赖于SharedPreferences的SettingsManager怎么办?根据上面的第3点,这应该需要添加一个返回SettingsManager的带注释的方法:@Module

public class ApplicationModule {

private final Application mApplication;

public ApplicationModule(Application application) {

mApplication = application;

}

@Provides

SharedPreferences provideSharedPreferences() {

return mApplication.getSharedPreferences(Constants.PREFERENCES_FILE, Context.MODE_PRIVATE);

}

@Provides

SettingsManager provideSettingsManager(SharedPreferences sharedPreferences) {

return new SettingsManager(sharedPreferences);

}

}请注意此新方法如何将SettingsManager所需的依赖项作为参数。关于我们到目前为止看到的内容,您可能(至少)有两个问题:谁调用了使用@Provides注释的Module方法?在provideSharedPreferences方法返回的SharedPreferences与provideSettingsManager方法的参数之间没有可见的连接。我们不应该将这些方法“连接”在一起吗?还记得我说过Dagger 2使用的是一个生成代码的预处理器吗?生成的代码可以解决上述问题。 在项目构建期间,预处理器扫描文件并生成调用@Provides注释注释方法的代码。它还确保对于声明为任何@Provides注释方法的参数的每个依赖项,都有一个实际提供该依赖项的方法。最后,生成的代码负责将所有@Provides注释方法“连接”在一起。通过处理所有“布线”活动,Dagger大大减少了您需要编写的样板代码量。ComponentDagger 2上下文中的组件是一个执行实际注入客户端的类(“注入器”)。 如果您熟悉术语“依赖注入容器”,那么组件就是其中之一。您不需要自己实现组件 - 框架的预处理器会生成它们。 但您确实需要“告诉”预处理器生成的组件应具有的功能。 这是通过声明用@Component注释接口来完成的。虽然我们声明的接口和预处理器生成的实际类是不同的实体,但它们通常都被称为组件。 可以从上下文中理解暗示哪个确切的实体。可以将ApplicationModule提供的服务注入MyApplication的组件声明示例:@Component(modules = {ApplicationModule.class})

public interface ApplicationComponent {

void inject(MyApplication myApplication);

}请注意以下事项:与我们到目前为止看到的其他注释不同,@ Component注释采用modules元素。 该元素告诉预处理器哪些模块将提供由该组件注入的服务。组件可以注入的每个客户端都被声明为单个void方法的参数。 方法名并不重要,但将它们称为注入是一种常见的约定。目前,此组件只能注入MyApplication。 如果我们想要使用框架注入MyActivity,该怎么办?根据上面的#2,这需要添加一个以MyActivity作为参数的void方法:@Component(modules = {ApplicationModule.class})

public interface ApplicationComponent {

void inject(MyApplication myApplication);

void inject(MyActivity myActivity);

}

如果我现在构建项目,框架的预处理器将扫描MyApplication和MyActivity类,以获取使用@Inject注释注释的字段。 然后预处理器将验证对于每个这样的字段,ApplicationModule中有一个提供所需服务的方法。在扫描客户端声明并确保确实提供所有必需服务之后,预处理器将生成ApplicationComponent接口的实现,该接口可用于注入MyApplication和MyActivity。自动生成的组件名称将是Dagger字符串,后跟组件接口的名称。 在这种情况下,名称将是DaggerApplicationComponent。Component用法现在,当您知道哪些组件是什么时,我们可以再次从帖子的开头查看MyApplication类。 这次你将更容易理解那里发生的事情:public class MyApplication extends Application {

@Inject SettingsManager mSettingsManager; // injectable field

private ApplicationComponent mApplicationComponent;

@Override

public void onCreate() {

getApplicationComponent().inject(this); // ApplicationComponent injects into "this" client

mSettingsManager.doSomething();

}

public ApplicationComponent getApplicationComponent() {

if (mApplicationComponent == null) {

mApplicationComponent = DaggerApplicationComponent.builder()

.applicationModule(new ApplicationModule(this))

.build();

}

return mApplicationComponent;

}

}

请注意以下事项:ApplicationComponent接口由我们定义。实现ApplicationComponent接口的DaggerApplicationComponent类是由框架的预处理器生成的。DaggerApplicationComponent类型的对象使用Builder模式进行实例化。我们必须手动实例化ApplicationModule并将其传递给DaggerApplicationComponent Builder。在继续之前,了解MyApplication类中每一行的作用非常重要。花点时间,清楚地了解正在发生的事情。具体来说,了解MyApplication中的代码如何与ApplicationComponent接口和ApplicationModule类中的代码相关联。您是否问过自己为什么在上面的示例中将ApplicationComponent分配给字段,以及为什么getApplicationComponent方法是公共的?这两种实现选择似乎都没有意义,因为ApplicationComponent只使用了一次。嗯,只要组件用于注入单个客户端,这确实没有意义。但是,一旦您需要使用ApplicationComponent将服务注入多个客户端,此代码将立即变得合理。假设您还希望使用ApplicationComponent注入MyActivity类。客户端的代码如下所示:public class MyActivity extends Activity {

@Inject SettingsManager mSettingsManager;

@Override

public void onCreate() {

((MyApplication)getApplication()).getApplicationComponent().inject(this);

}

@Override

public void onResume() {

mSettingsManager.doSomething();

}

}

请注意以下事项:为了使所有客户端都使用ApplicationComponent的相同实例,它必须存储在MyApplication类的字段中。为了使MyActivity能够访问ApplicationComponent的实例,方法getApplicationComponent()必须是公共的。此时可能不明显为什么要在所有客户端中使用相同的ApplicationComponent实例。 以下对范围的讨论将解释为什么它很重要。ScopeDagger 2上下文中的范围是一个注释,可用于更改注入服务的生命周期。我已经写了一篇关于范围的非常详细的帖子(https://www.techyourchance.com/dagger-2-scopes-demystified/),因此我不会在这里进行冗长的解释。 让我重新陈述主要范围的特征:每当同一组件注入非范围服务时,就会创建一个新的服务实例。第一次注入@Singleton作用域服务时,会在注入组件内创建并缓存一个新的服务实例。 在由相同组件注入相同类型的其他字段时将使用相同的实例。自定义用户定义的范围在功能上等同于预定义的@Singleton范围。由于我直到现在才使用本教程中的作用域,根据特性#1,所有客户端在前面的示例中都获得了不同的SettingsManager实例。让我们用Scopes改变这个。Scope用法现在想象一下,SettingsManager的实现包括一个非常复杂的内存缓存。由于缓存是内存中的,我必须确保依赖于SettingsManager的所有客户端都具有对同一实例的引用。否则,如果不同的客户端引用不同的实例,则一个客户端所做的更改将不会被另一个客户端看到,这将导致系统进入未定义和不一致的状态。上述要求的直接后果是SettingsManager必须成为“全局”对象。全局在这里意味着只要应用程序的进程处于活动状态,对象的实例就必须持久化。在Android中,有两种类型的全局对象: 静态字段引用的对象。 Application对象引用的对象(可能通过其他对象链引用)。类型1的全局对象正在Singleton反模式中使用。应不惜一切代价避免使用此类全局对象。另一方面,类型2的全局对象是必要且有用的。应用程序本身是类型2的全局对象。要在所有客户端共享SettingsManager中的内存缓存,我需要将SettingsManager转换为类型2的全局对象。为了实现这一点,我需要从MyApplication到它的一系列硬引用。由于此对象由DaggerApplicationComponent注入,因此第一个引用将从MyApplication到DaggerApplicationComponent。这解释了为什么我将DaggerApplicationComponent分配给MyApplication类中的字段。Dagger确保DaggerApplicationComponent在内部引用ApplicationModule。这将是链中的第二个参考。看起来我可以实现将SettingsManager转换为全局对象的目标,如果我能以某种方式使ApplicationModule存储对它的引用,并确保ApplicationModule稍后将始终提供此引用的注入实例。ApplicationModule的以下修改实现了我所需要的:@Module

public class ApplicationModule {

private final Application mApplication;

private SettingsManager mSettingsManager;

public ApplicationModule(Application application) {

mApplication = application;

}

@Provides

SharedPreferences provideSharedPreferences() {

return mApplication.getSharedPreferences(Constants.PREFERENCES_FILE, Context.MODE_PRIVATE);

}

@Provides

SettingsManager provideSettingsManager(SharedPreferences sharedPreferences) {

if (mSettingsManager == null) {

mSettingsManager = new SettingsManager(sharedPreferences);

}

return mSettingsManager;

}

}

上面的代码将SettingsManager转换为全局对象,并确保为所有客户端注入完全相同的实例。但是,我真的不需要自己编写所有这些代码。 事实证明,Dagger 2提供了自己的内置机制,允许注入服务的“全球化”。 此机制基于范围。根据前面提到的关于范围的帖子的特征#2,SettingsManager的“全球化”也可以通过以下对ApplicationModule的修改来实现:请注意,与原始实现的唯一区别是在提供SettingsManager的方法中添加了@Singleton注释。单注释方法比我自己编写的所有代码更简单,更简洁。框架的预处理器强制执行的一个限制是,如果组件注入作用域服务,则该组件也必须具有作用域,并且组件的范围必须与服务的范围相同。因此,为了编译代码,我还必须向ApplicationComponent添加范围:@Singleton

@Component(modules = {ApplicationModule.class})

public interface ApplicationComponent {

void inject(MyApplication myApplication);

void inject(MyActivity myActivity);

}

Dagger2的局限性Dagger2不会自动注入字段。它不能注入私有字段。如果要使用字段注入,则必须在@Component注释接口中定义一个方法,该接口接受要注入成员变量的类的实例。结论在这篇文章中,您学习了如何使用Dagger 2依赖注入框架实现基本的依赖注入体系结构模式。为什么“基本依赖注入架构模式”? 因为虽然这里提供的材料足以实现依赖注入,但在可维护性方面,该实现可能不是最佳的。在我看来,在Android中使用Dagger 2进行依赖注入的最佳实现必须使用本文未涉及的以下功能:多模块组件子组件您可以在我的Advanced Dagger 2视频教程中学习如何使用这些功能。编辑于 2019-01-08 13:50Android 开发依赖注入Dagger​赞同 2​​添加评论​分享​喜欢​收藏​申请

Dagger

Dagger

Home

Dagger

Hilt

Dagger Tutorial

Dagger

Dagger is a fully static, compile-time dependency injection framework for

Java, Kotlin, and Android. It is an adaptation of an

earlier version created by

Square and now maintained by Google.

The latest Dagger release is: Dagger 2.51

Dagger aims to address many of the development and performance issues that have

plagued reflection-based solutions. More details can be found in

this talk (slides) by

Gregory Kick.

Where are the docs?

User documentation

Dagger API @ HEAD

Where is the code?

https://github.com/google/dagger

Have a question?

Ask it on Stack Overflow with the dagger-2 tag

Send an email to dagger-discuss@googlegroups.com

© Dagger 2024

GitHub - google/dagger: A fast dependency injector for Android and Java.

GitHub - google/dagger: A fast dependency injector for Android and Java.

Skip to content

Toggle navigation

Sign in

Product

Actions

Automate any workflow

Packages

Host and manage packages

Security

Find and fix vulnerabilities

Codespaces

Instant dev environments

Copilot

Write better code with AI

Code review

Manage code changes

Issues

Plan and track work

Discussions

Collaborate outside of code

Explore

All features

Documentation

GitHub Skills

Blog

Solutions

For

Enterprise

Teams

Startups

Education

By Solution

CI/CD & Automation

DevOps

DevSecOps

Resources

Learning Pathways

White papers, Ebooks, Webinars

Customer Stories

Partners

Open Source

GitHub Sponsors

Fund open source developers

The ReadME Project

GitHub community articles

Repositories

Topics

Trending

Collections

Pricing

Search or jump to...

Search code, repositories, users, issues, pull requests...

Search

Clear

Search syntax tips

Provide feedback

We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

Sign up

You signed in with another tab or window. Reload to refresh your session.

You signed out in another tab or window. Reload to refresh your session.

You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

google

/

dagger

Public

forked from square/dagger

Notifications

Fork

2k

Star

17.3k

A fast dependency injector for Android and Java.

dagger.dev

License

Apache-2.0 license

17.3k

stars

3k

forks

Branches

Tags

Activity

Star

Notifications

Code

Issues

234

Pull requests

76

Actions

Projects

0

Wiki

Security

Insights

Additional navigation options

Code

Issues

Pull requests

Actions

Projects

Wiki

Security

Insights

google/dagger

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

 masterBranchesTagsGo to fileCode  Folders and filesNameNameLast commit messageLast commit dateLatest commit History4,067 Commits.allstar.allstar  .github.github  examplesexamples  gwtgwt  java/daggerjava/dagger  javatestsjavatests  third_partythird_party  toolstools  utilutil  .bazelrc.bazelrc  .gitignore.gitignore  AUTHORSAUTHORS  BUILDBUILD  CHANGELOG.mdCHANGELOG.md  CONTRIBUTING.mdCONTRIBUTING.md  LICENSE.txtLICENSE.txt  README.mdREADME.md  WORKSPACEWORKSPACE  build_defs.bzlbuild_defs.bzl  test_defs.bzltest_defs.bzl  workspace_defs.bzlworkspace_defs.bzl  View all filesRepository files navigationREADMECode of conductApache-2.0 licenseSecurityDagger

A fast dependency injector for Java and Android.

Dagger is a compile-time framework for dependency injection. It uses no

reflection or runtime bytecode generation, does all its analysis at

compile-time, and generates plain Java source code.

Dagger is actively maintained by Google. Snapshot releases are auto-deployed to

Sonatype's central Maven repository on every clean build with the version

HEAD-SNAPSHOT. The current version builds upon previous work done at Square.

Documentation

You can find the dagger documentation here which has extended usage

instructions and other useful information. More detailed information can be

found in the API documentation.

You can also learn more from the original proposal,

this talk by Greg Kick, and on the dagger-discuss@googlegroups.com

mailing list.

Installation

Bazel

First, import the Dagger repository into your WORKSPACE file using

http_archive.

Note: The http_archive must point to a tagged release of Dagger, not just any

commit. The version of the Dagger artifacts will match the version of the tagged

release.

# Top-level WORKSPACE file

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

DAGGER_TAG = "2.51"

DAGGER_SHA = "de18b83a7b8ca43f5ab604d41228e11805ee5c0e4aa229d3e692addd994e6ff8"

http_archive(

name = "dagger",

strip_prefix = "dagger-dagger-%s" % DAGGER_TAG,

sha256 = DAGGER_SHA,

urls = ["https://github.com/google/dagger/archive/dagger-%s.zip" % DAGGER_TAG],

)

Next you will need to setup targets that export the proper dependencies

and plugins. Follow the sections below to setup the dependencies you need.

Dagger Setup

First, load the Dagger artifacts and repositories, and add them to your list of

maven_install artifacts.

# Top-level WORKSPACE file

load("@dagger//:workspace_defs.bzl", "DAGGER_ARTIFACTS", "DAGGER_REPOSITORIES")

maven_install(

artifacts = DAGGER_ARTIFACTS + [...],

repositories = DAGGER_REPOSITORIES + [...],

)

Next, load and call dagger_rules

in your top-level BUILD file:

# Top-level BUILD file

load("@dagger//:workspace_defs.bzl", "dagger_rules")

dagger_rules()

This will add the following Dagger build targets:

(Note that these targets already export all of the dependencies and processors

they need).

deps = [

":dagger", # For Dagger

":dagger-spi", # For Dagger SPI

":dagger-producers", # For Dagger Producers

]

Dagger Android Setup

First, load the Dagger Android artifacts and repositories, and add them to your

list of maven_install artifacts.

# Top-level WORKSPACE file

load(

"@dagger//:workspace_defs.bzl",

"DAGGER_ANDROID_ARTIFACTS",

"DAGGER_ANDROID_REPOSITORIES"

)

maven_install(

artifacts = DAGGER_ANDROID_ARTIFACTS + [...],

repositories = DAGGER_ANDROID_REPOSITORIES + [...],

)

Next, load and call dagger_android_rules

in your top-level BUILD file:

# Top-level BUILD file

load("@dagger//:workspace_defs.bzl", "dagger_android_rules")

dagger_android_rules()

This will add the following Dagger Android build targets:

(Note that these targets already export all of the dependencies and processors

they need).

deps = [

":dagger-android", # For Dagger Android

":dagger-android-support", # For Dagger Android (Support)

]

Hilt Android Setup

First, load the Hilt Android artifacts and repositories, and add them to your

list of maven_install artifacts.

# Top-level WORKSPACE file

load(

"@dagger//:workspace_defs.bzl",

"HILT_ANDROID_ARTIFACTS",

"HILT_ANDROID_REPOSITORIES"

)

maven_install(

artifacts = HILT_ANDROID_ARTIFACTS + [...],

repositories = HILT_ANDROID_REPOSITORIES + [...],

)

Next, load and call hilt_android_rules

in your top-level BUILD file:

# Top-level BUILD file

load("@dagger//:workspace_defs.bzl", "hilt_android_rules")

hilt_android_rules()

This will add the following Hilt Android build targets:

(Note that these targets already export all of the dependencies and processors

they need).

deps = [

":hilt-android", # For Hilt Android

":hilt-android-testing", # For Hilt Android Testing

]

Other build systems

You will need to include the dagger-2.x.jar in your application's runtime.

In order to activate code generation and generate implementations to manage

your graph you will need to include dagger-compiler-2.x.jar in your build

at compile time.

Maven

In a Maven project, include the dagger artifact in the dependencies section

of your pom.xml and the dagger-compiler artifact as an

annotationProcessorPaths value of the maven-compiler-plugin:

com.google.dagger

dagger

2.x

org.apache.maven.plugins

maven-compiler-plugin

3.6.1

com.google.dagger

dagger-compiler

2.x

If you are using a version of the maven-compiler-plugin lower than 3.5, add

the dagger-compiler artifact with the provided scope:

com.google.dagger

dagger

2.x

com.google.dagger

dagger-compiler

2.x

provided

If you use the beta dagger-producers extension (which supplies

parallelizable execution graphs), then add this to your maven configuration:

com.google.dagger

dagger-producers

2.x

Gradle

// Add Dagger dependencies

dependencies {

implementation 'com.google.dagger:dagger:2.x'

annotationProcessor 'com.google.dagger:dagger-compiler:2.x'

}

If you're using classes in dagger.android you'll also want to include:

implementation 'com.google.dagger:dagger-android:2.x'

implementation 'com.google.dagger:dagger-android-support:2.x' // if you use the support libraries

annotationProcessor 'com.google.dagger:dagger-android-processor:2.x'

Notes:

We use implementation instead of api for better compilation performance.

See the Gradle documentation for more

information on how to select appropriately, and the Android Gradle

plugin documentation for Android

projects.

For Kotlin projects, use kapt in place of annotationProcessor.

If you're using the Android Databinding library, you may want to

increase the number of errors that javac will print. When Dagger prints an

error, databinding compilation will halt and sometimes print more than 100

errors, which is the default amount for javac. For more information, see

Issue 306.

gradle.projectsEvaluated {

tasks.withType(JavaCompile) {

options.compilerArgs << "-Xmaxerrs" << "500" // or whatever number you want

}

}

Resources

Documentation

Javadocs

GitHub Issues

If you do not use maven, gradle, ivy, or other build systems that consume

maven-style binary artifacts, they can be downloaded directly via the

Maven Central Repository.

Developer snapshots are available from Sonatype's

snapshot repository, and are built on a clean build of

the GitHub project's master branch.

Building Dagger

See the CONTRIBUTING.md docs.

License

Copyright 2012 The Dagger Authors

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

About

A fast dependency injector for Android and Java.

dagger.dev

Resources

Readme

License

Apache-2.0 license

Code of conduct

Code of conduct

Security policy

Security policy

Activity

Custom properties

Stars

17.3k

stars

Watchers

535

watching

Forks

2k

forks

Report repository

Releases

89

Dagger 2.51

Latest

Feb 28, 2024

+ 88 releases

Packages

0

No packages published

Used by 2.1k

+ 2,074

Languages

Java

80.8%

Kotlin

11.9%

Starlark

6.9%

Other

0.4%

Footer

© 2024 GitHub, Inc.

Footer navigation

Terms

Privacy

Security

Status

Docs

Contact

Manage cookies

Do not share my personal information

You can’t perform that action at this time.

Imitation Learning Ⅱ: DAgger透彻理论分析 - 知乎

Imitation Learning Ⅱ: DAgger透彻理论分析 - 知乎首发于RL in Robotics切换模式写文章登录/注册Imitation Learning Ⅱ: DAgger透彻理论分析刘浚嘉​上海交通大学 机械工程硕士A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning2010 | Paper | CMUStéphane Ross, Geoffrey J. Gordon, J. Andrew Bagnell承接上文 Imitation Learning: An Introduction,我们详细地看一下提出DAgger的paper。本post主要讨论为什么这样的非独立同分布的在线学习思想是可以work并收敛的。DAgger旨在解决模仿学习的两个问题:传统的学习一个classifier或regressor的方式,不适用于序列决策过程。因为t时刻的预测会影响t+1, ..., t+n时刻的状态,这违背了统计学中的 iid(独立同分布假设);误差累积。DATASET AGGREGATION Algorithm简而言之,DAgger在每一次迭代中利用当前的policy收集数据,然后利用所有的数据集训练下一次的policy。先设 \beta_1=1 ,即用expert policy获取初始数据。然后再随着训练过程指数级衰减这个系数 \beta_i=p^{i-1} .理论分析DAgger是一种增量学习(Incremental learning)/在线学习(Online learning)的思想。No-regret Algorithmno-regret是啥?这篇paper是这么写的:如果一个算法,其产生的一系列策略 \pi_{1}, \pi_{2}, \ldots, \pi_{N} ,当N变为无穷时,对事后(hindsight)最佳策略的平均后悔(regret)变为0: \frac{1}{N} \sum_{i=1}^{N} \ell_{i}\left(\pi_{i}\right)-\min _{\pi \in \Pi} \frac{1}{N} \sum_{i=1}^{N} \ell_{i}(\pi) \leq \gamma_{N}\\ Well,没懂。所幸我在reddit上找到了答案,参照 Prediction, Learning, and Games 这本教材的11页,16-17页,给出如下定义:regret 指预测者(forecaster)的累计损失与专家(expert)之间的差,其用于度量预测者在事后有多后悔没有跟随专家的指导。很显然,DAgger这里把最佳策略 \pi 是为了expert策略,no-regret 代表着随着训练地迭代,我们可以让这个差趋近于0。也可以看看 在线学习 这篇博客。DAgger 的 no-regret guaranteesDAgger是否符合我们上面提到的No-regret Algorithm呢?引理 4.1: \left\|d_{\pi_{i}}-d_{\hat{\pi}_{i}}\right\|_{1} \leq 2 T \beta_{i} d代表状态分布。由于伪码中, \pi_{i}=\beta_{i} \pi^{*}+\left(1-\beta_{i}\right) \hat{\pi}_{i} 故有, d_{\pi_{i}}=\left(1-\beta_{i}\right)^{T} d_{\hat{\pi}_{i}}+\left(1-\left(1-\beta_{i}\right)^{T}\right) d \begin{array}{l} \left\|d_{\pi_{i}}-d_{\hat{\pi}_{i}}\right\|_{1} \\ =\left(1-\left(1-\beta_{i}\right)^{T}\right)\left\|d-d_{\hat{\pi}_{i}}\right\|_{1} \\ \leq 2\left(1-\left(1-\beta_{i}\right)^{T}\right) \\ \leq 2 T \beta_{i} \end{array}\\ Theorem 4.1: For DAGGER, 存在一个策略 \hat{\pi} \in\hat{\pi}_{1: N} ,使 \mathbb{E}_{s \sim d_{\widehat{\pi}}}[\ell(s, \hat{\pi})] \leq \epsilon_{N}+\gamma_{N}+\frac{2 \ell_{\max }}{N}\left[n_{\beta}+\right.\left.T \sum_{i=n_{\beta}+1}^{N} \beta_{i}\right], for \gamma_{N} the average regret of \hat{\pi}_{1: N} 上面的定理保证了这样一个online learning方法在infinite sample上可以做到no-regret。然而实际中我们只能有限采样(finite sample)。Theorem 4.2: For DAGGER, 有至少 $ 1-\delta 的概率存在这样一个策略 \hat{\pi} \in \hat{\pi}{1: N} ,使 \mathbb{E}_{s \sim d_{\widehat{\pi}}}[\ell(s, \hat{\pi})] \leq \hat{\epsilon}_{N}+\gamma_{N}+\frac{2 \ell_{\max }}{N}\left[n_{\beta}+T \sum_{i=n_{\beta}+1}^{N} \beta_{i}\right]+\ell_{\max } \sqrt{\frac{2 \log (1 / \delta)}{m N}}, for \gamma_{N} ​ the average regret of \hat{\pi}_{1: N}​ 编辑于 2020-05-15 10:33深度学习(Deep Learning)强化学习 (Reinforcement Learning)在线学习​赞同 61​​8 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录RL in RoboticsFocusing on but not limited to the application of reinforcement learning in robotics, founded for real intelligen

Releases · google/dagger · GitHub

Releases · google/dagger · GitHub

Skip to content

Toggle navigation

Sign in

Product

Actions

Automate any workflow

Packages

Host and manage packages

Security

Find and fix vulnerabilities

Codespaces

Instant dev environments

Copilot

Write better code with AI

Code review

Manage code changes

Issues

Plan and track work

Discussions

Collaborate outside of code

Explore

All features

Documentation

GitHub Skills

Blog

Solutions

For

Enterprise

Teams

Startups

Education

By Solution

CI/CD & Automation

DevOps

DevSecOps

Resources

Learning Pathways

White papers, Ebooks, Webinars

Customer Stories

Partners

Open Source

GitHub Sponsors

Fund open source developers

The ReadME Project

GitHub community articles

Repositories

Topics

Trending

Collections

Pricing

Search or jump to...

Search code, repositories, users, issues, pull requests...

Search

Clear

Search syntax tips

Provide feedback

We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

Sign up

You signed in with another tab or window. Reload to refresh your session.

You signed out in another tab or window. Reload to refresh your session.

You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

google

/

dagger

Public

forked from square/dagger

Notifications

Fork

2k

Star

17.3k

Code

Issues

234

Pull requests

76

Actions

Projects

0

Wiki

Security

Insights

Additional navigation options

Code

Issues

Pull requests

Actions

Projects

Wiki

Security

Insights

Releases: google/dagger

Releases

Tags

Releases · google/dagger

Dagger 2.51

28 Feb 22:07

wanyingd1996

dagger-2.51

c6c0b8a

Compare

Choose a tag to compare

View all tags

Dagger 2.51

Latest

Latest

New Dagger Features

Added a @LazyClassKey annotation that supports using class names as a map key. Unlike the existing @ClassKey, the map generated by @LazyClassKey won’t eagerly load all of the classes for the keys. This can be useful in situations or environments where classloading can be expensive, such as on Android. For more information, see https://dagger.dev/dev-guide/multibindings

Potential breaking changes

Protected fields using @Inject are now banned in Kotlin classes. This is because Kotlin protected fields are not accessible by code in the same package, unlike Java. This has been working up to this point because Dagger generates Java code, but that is unintentional and would break if Dagger switched to generate Kotlin code.(408431a)

New Hilt Features

Fixed #3197: Used the new @LazyClassKey Dagger feature to remove the keep rule for @HiltViewModel class names. This allows obfuscation of @HiltViewModel annotated ViewModel class names with R8. (0786d0a)

Added @SkipTestInjection which can be used for skipping test injection in Hilt Android tests, which may be useful if building separate custom test infrastructure to inject the test class from another Hilt component. (c40811e)

Dagger bug fixes

Improve Dagger MissingBinding error messages to give more information and be more consistent. (c872238)

Fixed #4201: Suppress warning for casting in Dagger generated code. (813ffce)

Fixed #4203: Removes @Deprecated annotation causing warnings (3cbc94a)

Fixed #4199: Support member injections from type aliased superclass (662d823)

Complete Ksp support for Dagger Android: Added a Ksp Processor for Dagger Android ProguardProcessor that was previously missed. The ProguardProcessor is a Dagger Android implementation detail that makes sure the AndroidInjector works correctly when shrinking tools obfuscate @ContributesAndroidInjector annotated injector class names. (e71de27)

Assets

2

16

primdugno, SteinerOk, IsakTheHacker, trietbui85, guuilp, Lavmee, arohim, Rafael2616, sphrak, yopachara, and 6 more reacted with thumbs up emoji

3

IsakTheHacker, sphrak, and huynhdev24 reacted with laugh emoji

11

audkar, SteinerOk, IsakTheHacker, tinder-levonpetrosyan, anhnmt, arohim, sphrak, yopachara, AlexKrupa, ParaskP7, and Junzz0 reacted with hooray emoji

❤️

6

IsakTheHacker, SteinerOk, arohim, sphrak, alexrwegener, and ParaskP7 reacted with heart emoji

6

IsakTheHacker, kosenda, sphrak, yopachara, itsandreramon, and ParaskP7 reacted with rocket emoji

2

IsakTheHacker and arohim reacted with eyes emoji

All reactions

16 reactions

3 reactions

11 reactions

❤️

6 reactions

6 reactions

2 reactions

24 people reacted

Dagger 2.50

19 Dec 23:57

Chang-Eric

dagger-2.50

137995b

Compare

Choose a tag to compare

View all tags

Dagger 2.50

Dagger

Potential breaking changes

Introduced a new dagger.internal.Provider to facilitate future support for jakarta.inject.Provider types. There should be no visible changes at this time, though with such a large change there is a risk of unanticipated version compatibility issues across libraries built with different Dagger versions. (75d3cbc)

Flip the default for -Adagger.explicitBindingConflictsWithInject to enabled. This flag fixes a bug where an explicit binding like an @Provides should conflict with @Inject bindings if the @Inject is actually used in a parent component. (8372c63)

Bug fixes

Fixed the error message for an @Binds @IntoSet implementation with duplicate bindings. (8d01223)

Assets

2

10

NicosNicolaou16, alibagherifam, Javernaut, SteinerOk, sphrak, IsakTheHacker, kosenda, macsystems, nitinlondhe2113, and mdocevski-infinum reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

13

Ecgbert, EdricChan03, primdugno, itsandreramon, audkar, fobo66, dominh2000, sphrak, IsakTheHacker, alibagherifam, and 3 more reacted with hooray emoji

❤️

3

sphrak, IsakTheHacker, and Eganathan reacted with heart emoji

1

IsakTheHacker reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

10 reactions

1 reaction

13 reactions

❤️

3 reactions

1 reaction

1 reaction

21 people reacted

Dagger 2.49

01 Dec 21:04

bcorso

dagger-2.49

d763c2c

Compare

Choose a tag to compare

View all tags

Dagger 2.49

Dagger

New features:

Fixed #4044: Add support for KSP with dagger.android (8327177).

Potential breaking changes:

Dagger’s generated component no longer contains deprecated no-op module setter methods for modules that have only static/abstract @Provides/@Binds methods (ed47d4b).

Note: If you hit this issue, the fix is to remove the call to the setter method in your code. For example:

MyComponent component =

DaggerMyComponent.builder()

- .moduleWithOnlyStaticOrAbstractMethods(new ModuleWithOnlyStaticOrAbstractMethods())

.build();

These setter methods were already no-ops (i.e. Dagger just ignored them), so removing it should not cause any functional changes.

Bug fixes:

Fixed #4046, #4140: Fixes Unexpected element error in when calculating nullability (4593c0a)

Fixed #4096: Fix type names for inline types on the KSP side (aosp/2789273)

Build-time performance improvements (85e9ff1) and (d9d0a8e).

Fixed #4060: Updated KSP to 1.9.20-1.0.14 which should contain the fix for a number of incremental processing issues related to KSP (692015f).

Hilt

New features:

Fixed #2287, #3523: Add support for using @AssistedInject with @HiltViewModel. (8327177).

For more details visit https://dagger.dev/hilt/view-model#assisted-injection.

Hilt now provides @ActivityRetainedSavedState SavedStateHandle from ActivityRetainedComponent (1cac33b).

Note: This feature relies on a somewhat experimental implementation in order to provide this binding lazily while also avoiding leaking the activity. The laziness is a requirement to not restrict activity injection and also to avoid bloating the saved state when unused. While we predict this should be safe to rely on, if issues are discovered with this implementation, it is possible that a future release may have to remove this binding.

Bug fixes:

Fixed b/307592550: Fixes FileNotFoundException in AGP 8.3 (6018cd2) and (f946e34).

Fixed #4130: Fix HiltGradlePlugin not working in KMP's androidMain directory (f0c2510).

Assets

2

23

NicosNicolaou16, JailedBird, ParaskP7, kemaltunc, alibagherifam, EdricChan03, IsakTheHacker, sphrak, YosuaPWH, BobNich, and 13 more reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

12

ParaskP7, jbduncan, kemaltunc, EdricChan03, IsakTheHacker, sphrak, sbilsky, mustafaberkaymutlu, Dragonwrath, EhsanMsz, and 2 more reacted with hooray emoji

❤️

10

sphrak, ParaskP7, nesyou01, EdricChan03, IsakTheHacker, sbilsky, cbeyls, sokarcreative, ZhaohuaZeng-at, and AlessandroFrangiamone reacted with heart emoji

24

jonapoul, tinder-levonpetrosyan, michael-crompton, SimonMarquis, wanyingd1996, sphrak, msfjarvis, NUmeroAndDev, ParaskP7, kemaltunc, and 14 more reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

23 reactions

1 reaction

12 reactions

❤️

10 reactions

24 reactions

1 reaction

44 people reacted

Dagger 2.48.1

03 Oct 22:15

bcorso

dagger-2.48.1

2d9ba60

Compare

Choose a tag to compare

View all tags

Dagger 2.48.1

Bug Fixes

Fixes #4063, #4054: [KSP]: Fixes some incremental processing issues with KSP (c8a568956)

Fixes #4046: [KSP] Fixes "Unexpected element" in XProcessing library (androidx/androidx@bdc1bb0)

Fixes #4059: [KSP] Align behavior of generic inline types in KSP with KAPT in XProcessing library (androidx/androidx@b0fa9cf)

Fixes #3980: Fixes Lint crash with AGP 8.1.0. (e651294)

Fixes #4055: Fixes issue with using generic types in Dagger's ClassKey (9852b42)

Assets

2

10

NicosNicolaou16, roomtek, rakshitsoni02, bjarneheden, achie, tevjef, nathankim0, rcgonzalezf, SteinerOk, and IsakTheHacker reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

17

TonyTangAndroid, AhmedElmasry700, sphrak, G00fY2, Siedlerchr, kyrillosgait, msfjarvis, kuanyingchou, KEVINGILBERTTODING, ZhaohuaZeng-at, and 7 more reacted with hooray emoji

❤️

1

IsakTheHacker reacted with heart emoji

21

EdricChan03, easyhooon, PedroFrr, TonyTangAndroid, Ecgbert, JailedBird, sphrak, primdugno, kyrillosgait, rustamsafarovrs, and 11 more reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

10 reactions

1 reaction

17 reactions

❤️

1 reaction

21 reactions

1 reaction

36 people reacted

Dagger 2.48

30 Aug 16:28

bcorso

dagger-2.48

03513e5

Compare

Choose a tag to compare

View all tags

Dagger 2.48

Dagger 2.48

Dagger/Hilt KSP support

Dagger 2.48 includes the alpha release of the Dagger and Hilt KSP processors.

Instructions for using the Dagger/Hilt KSP processors can be found at https://dagger.dev/dev-guide/ksp.

In order to use Dagger’s KSP processor you will need to:

Follow the basic setup to migrate Dagger’s processors from kapt to ksp (see https://dagger.dev/dev-guide/ksp#setup).

Migrate any Dagger SPI plugins to the new Dagger SPI plugins API (with KSP support) (see https://dagger.dev/dev-guide/ksp#new-dagger-spi-plugin-with-ksp-support).

Ensure that there are no kapt processors that generate classes that need to interact with Dagger (see https://dagger.dev/dev-guide/ksp#interaction-with-javackapt-processors).

If you depend on androidx.hilt:hilt-common or androidx.hilt:hilt-work they will need to be updated to at least 1.1.0-alpha01.

Also note that Dagger’s KSP processors are still in the alpha stage. So far we’ve focused mainly on trying to ensure correctness rather than optimize performance. Please apply due diligence when enabling ksp and report any bugs or performance issues at https://github.com/google/dagger/issues. The current list of known issues can be found here.

There are also a few potentially breaking changes included with this release. These changes were made to better support Dagger usage with Kotlin sources, and make the migration from KAPT to KSP more seamless. We don’t expect these changes to affect most users. Please see below for more details.

Breaking changes

The dagger.ignoreProvisionKeyWildcards is now enabled by default

This may break apps that are providing the same binding with different wildcards, e.g. Foo and Foo.

Fix: See https://dagger.dev/dev-guide/compiler-options#ignore-provision-key-wildcards for suggestions on how to fix this. If fixing is not an immediate option, you can still disable the flag with dagger.ignoreProvisionKeyWildcards=DISABLED.

@Binds assignability check

Unlike KAPT, KSP takes nullability into account when checking if a type is assignable to another type. This changes the behavior of Dagger’s @Binds usage validation such that a type that was assignable in KAPT may no longer be assignable in KSP. For example:

// Incorrect: this compiles successfully in KAPT but the compilation fails in KSP

@Binds fun bind(impl: FooImpl): Foo

Fix: To fix this breakage, users should update the parameter or return type in the method such that they are actually assignable when taking nullability into account. For example:

// Correct: this compiles successfully in KAPT and KSP

@Binds fun bind(impl: FooImpl): Foo

Top-level @Module / @Inject classes can no longer be private

Top-level @Module or @Inject classes can no longer be private. This was previously allowed purely by accident (rather than being an officially supported feature) due to the way Kotlin’s private classes are represented as package-private in KAPT’s generated java stubs.

Fix: Replace the private visibility modifier with internal or public.

@Binds and @Provides methods can no longer be extension functions

Normally when we define an @Provides/@Binds function we put the dependencies in the parameter list:

@Module

abstract class BarModule {

@Binds

abstract fun bindsBar(@Marker foo: Foo): Bar

}

However, since the introduction of KAPT, it was also technically possible to define an @Provides/@Binds function using an extension function:

@Module

abstract class BarModule {

@Binds

abstract fun @receiver:Marker Foo.bindsBar(): Bar

}

This extension function syntax worked more by coincidence (rather than being an officially supported feature) due to the way extension functions are represented in KAPT’s generated java stubs. After review, we’ve decided not to support this feature anymore in KAPT or KSP. See more at #3990.

Fix: Use the traditional parameter approach rather than extension functions.

The use of abstract var properties are no longer allowed in components

A var property adds both a getter (aka request) method and a setter (aka injection) method for a binding. However, the setter method typically goes unused since there is rarely a case for needing both methods for a single binding. After discussion within the team, we’ve decided to ban abstract var properties in components.

Fix: Use fun (or val) for getter methods, use fun for setter methods.

Other changes

Fixed #3995: Allow kotlin source to use java keywords as parameter names in KSP (2c31d66).

Fixed #3991: Fixed error message when there are multiple @Inject + @AssistedInject constructors (9105ee671).

Fixed #3992: Fixed crash crash when there are multiple @AssistedInject + @AssistedInject constructors (9105ee671.)

Add a better error message when Hilt Gradle Plugin class loader conflicts with KSP's Gradle plugin. (3f7b9b5)

Assets

2

66

NicosNicolaou16, zdenekobornik, kikogassen, efemoney, kakai248, Zhuinden, sureshmaidaragi1919, jbduncan, ritesh-singh, Hecatoncheir, and 56 more reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

136

mateuszkwiecinski, audkar, Rafael2616, wanyingd1996, vitorhugods, feicien, alirezaHabibpour, dominh2000, rschattauer, msfjarvis, and 126 more reacted with hooray emoji

❤️

61

mateuszkwiecinski, Rafael2616, Tgo1014, vitorhugods, rschattauer, bogdanzurac, EdricChan03, kaeawc, zdenekobornik, kikogassen, and 51 more reacted with heart emoji

74

mateuszkwiecinski, tevjef, sockeqwe, vitorhugods, bacecek, zoonooz, thomaskioko, workspace, bogdanzurac, EdricChan03, and 64 more reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

66 reactions

1 reaction

136 reactions

❤️

61 reactions

74 reactions

1 reaction

208 people reacted

Dagger 2.47

14 Jul 00:43

Chang-Eric

dagger-2.47

20892bf

Compare

Choose a tag to compare

View all tags

Dagger 2.47

What’s new In Dagger

A new default disabled flag dagger.ignoreProvisionKeyWildcards has been added. Enabling this flag will be required to use KSP in a future release. For more information on this flag, see the documentation here: https://dagger.dev/dev-guide/compiler-options#ignore-provision-key-wildcards

Bug Fixes

Update kotlinx-metadata-jvm to 0.6.2 Fixes #3893. (7b16dfd)

Disallow private modules in Kotlin sources (already disallowed in Java sources). There is an issue with KAPT where the generated stubs for a private Kotlin module would not be private. To prepare for KSP support where the Kotlin source is read directly, this is fixed to be an error as it should have been. (53fd1a4)

What’s new in Hilt

The Hilt Android Gradle plugin will now enforce a minimum Android Gradle plugin (AGP) version of 7.0. (e512d87)

Deprecated the enableTransformForLocalTests option in the Hilt Android Gradle plugin. This is no longer necessary as the minimum supported AGP version has been increased to 7.0. (b3fd56f)

Assets

2

1

IsakTheHacker reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

17

tinder-levonpetrosyan, sezeranoJchrisostome, ParaskP7, MyDogTom, sphrak, primdugno, TheHemantKaushik, romainhamm, yannickpulver, sebastinto, and 7 more reacted with hooray emoji

❤️

1

IsakTheHacker reacted with heart emoji

9

hashlin, ParaskP7, itsandreramon, MarekMacko, sphrak, audkar, TheHemantKaushik, dboonzaier-godaddy, and IsakTheHacker reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

1 reaction

1 reaction

17 reactions

❤️

1 reaction

9 reactions

1 reaction

21 people reacted

Dagger 2.46.1

12 May 21:22

bcorso

dagger-2.46.1

ee7920c

Compare

Choose a tag to compare

View all tags

Dagger 2.46.1

What’s new In Dagger

Bug Fixes

Fixed #3701: Shade kotlinx metadata in Dagger's artifacts to prevent upstream dependency issues. (d593e01)

Assets

2

1

IsakTheHacker reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

17

fatih-ozturk, dharmakshetri, marctatham, MathRoda, Magicontrol, ParaskP7, hnljp, gianlucaLana, Svilcata19, Alexzenderus, and 7 more reacted with hooray emoji

❤️

1

IsakTheHacker reacted with heart emoji

7

fatih-ozturk, zhaonian, ParaskP7, kokoichi206, davthecodercom, FrankEsery, and IsakTheHacker reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

1 reaction

1 reaction

17 reactions

❤️

1 reaction

7 reactions

1 reaction

19 people reacted

Dagger 2.46

28 Apr 21:06

bcorso

dagger-2.46

0e6824b

Compare

Choose a tag to compare

View all tags

Dagger 2.46

What’s new In Dagger

Bug Fixes

Fixed #3701 and #3838. Updated Dagger to kotlinx metadata 0.6.0. (7cf53031)

Assets

2

1

IsakTheHacker reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

17

G00fY2, dangolbeeker, fobo66, Javernaut, mohsen2986, fatih-ozturk, nesyou01, ParaskP7, kurtlzen, gsprdev, and 7 more reacted with hooray emoji

❤️

1

IsakTheHacker reacted with heart emoji

1

IsakTheHacker reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

1 reaction

1 reaction

17 reactions

❤️

1 reaction

1 reaction

1 reaction

17 people reacted

Dagger 2.45

10 Feb 00:50

Chang-Eric

dagger-2.45

22705fb

Compare

Choose a tag to compare

View all tags

Dagger 2.45

Dagger 2.45

What’s new In Dagger

Bug Fixes

Fixed an issue where a scoped @Binds used in a cycle would cause an NPE on component creation in fastInit mode. (fae46c7)

Fixed #3677. Added a better error message for when @Multibinds types incorrectly used framework types like Provider. (f5ad2b2)

Fixed an issue where when giving a missing binding error, an available matching binding in another component would not be suggested if the matching binding was otherwise unused. (00d84ba)

What’s new in Hilt

Bug Fixes

Fixed #3546. Filtered the compiler args passed to hiltJavaCompile in the Hilt Gradle plugin to avoid overlapping outputs and cache misses. (b7c0d3e)

Improved the error message when @HiltAndroidApp is not used in an app module (ffaa7a6)

Assets

2

1

IsakTheHacker reacted with thumbs up emoji

1

IsakTheHacker reacted with laugh emoji

7

ParaskP7, G00fY2, Rizky92, kakai248, hoangcongtuan, cleysondiego, and IsakTheHacker reacted with hooray emoji

❤️

1

IsakTheHacker reacted with heart emoji

4

uhooi, hoangcongtuan, DanteTran1103, and IsakTheHacker reacted with rocket emoji

1

IsakTheHacker reacted with eyes emoji

All reactions

1 reaction

1 reaction

7 reactions

❤️

1 reaction

4 reactions

1 reaction

9 people reacted

Dagger 2.44.2

14 Nov 18:53

bcorso

dagger-2.44.2

35a18c4

Compare

Choose a tag to compare

View all tags

Dagger 2.44.2

What’s new in Dagger

Bug fixes

Fixes #3633: Updated shading rules to include newly added classes in androidx.room.compiler to prevent class version conflicts with user dependency on Room.

Assets

2

14

audkar, imashnake0, ParaskP7, MrGreen39, anthonymonori, BAndersonMatjik, respartner, hubtwork, voytovichs, hlayan, and 4 more reacted with hooray emoji

2

uhooi and Santrucho reacted with rocket emoji

All reactions

14 reactions

2 reactions

16 people reacted

Previous 1 2 3 4 5 … 8 9 Next

Previous Next

Footer

© 2024 GitHub, Inc.

Footer navigation

Terms

Privacy

Security

Status

Docs

Contact

Manage cookies

Do not share my personal information

You can’t perform that action at this time.

神兵利器Dagger2一站式全解(详细总结)-CSDN博客

>

神兵利器Dagger2一站式全解(详细总结)-CSDN博客

神兵利器Dagger2一站式全解(详细总结)

最新推荐文章于 2023-11-28 23:04:07 发布

VIP文章

蔚1

最新推荐文章于 2023-11-28 23:04:07 发布

阅读量1.1w

收藏

51

点赞数

11

文章标签:

移动开发

java

runtime

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/valada/article/details/106225715

版权

Dagger2 在模块间解耦、提高代码的健壮性和可维护性方面是当之无愧的“利器”,github star 15k。

文章适合人群:对 Dagger2 感兴趣但还未真正开始学习、对 Dagger2 学习过一些但没有成体系而知识片面、有意向成为 Java/Android 高级开发的程序员。

Chat 主要内容有:

Dagger2 的简介;

Dagger2的注解;

Dagger2 的使用;

Dagger2 的单例模式;

Dagger2 的懒/重加载;

Dagger2 中 Component 组织依赖关系;

Dagger2 的用途总结和原理分析;

最后:教学相长,欢迎大家一起交流学习。

依赖注入框架 Dagger2 起源于 Dagger,官网地址是 https://google.github.io/dagger/ ,是一款基于 Java 注解来实现的完全在编译阶段完成依赖注入的开源库。Dagger2 应于 Java 和 Android 开发而不单单是 Android,主要用于模块间解耦、提高代码的健壮性和可维护性。

Dagger2 在编译阶段通过 apt 利用 Java 注解自动生成 Java 代码,然后结合手写的代码来自动帮我们完成依赖注入的工作。它需要先编译一次代码,目的是为了生成中间代码,然后在中间代码的基础上按照正常的流程开发。我们知道反射处理相对于正常开发速度而言会慢一点,但 Dagger2 却不会有这样的缺点,它巧妙地把反射处理移动到编译器编译代码时的阶段,而程序运行时并不涉及到反射,而是通过生成代码的方式来达到注入效果的,在 Android 的很多开源框架中都是用到了代码生成工具(APT), 比如 ButterKnife、GreenDao 等三方库等。

二 Dagger2 注解初识

Dagger2 是基于 Java 注解来实现依赖注入的,那么在正式使用之前我们需要先了解下 Dagger2 中的注解。Dagger2 使用过程中我们通常接触到的注解主要包括:@Inject, @Module, @Provides, @Component, @Qulifier, @Scope, @Singleten。

2.1 @Inject:

@Inject 有两个作用:

一是用来标记需要依赖的变量,以此告诉 Dagger2 为它提供依赖;

二是用来标记构造函数,Dagger2 通过@Inject 注解可以在需要这个类实例的时候来找到这个构造函数并把相关实例构造出来,以此来为被@Inject 标记了的变量提供依赖;

参考 demo:3.2 节案例 A。

2.2 @Module:

@Module 用于标注提供依赖的类。你可能会有点困惑,上面不是提到用@Inject 标记构造函数就可以提供依赖了么,为什么还需要@Module?

比如,很多时候我们需要提供依赖的构造函数是第三方库的,我们没法给它加上@Inject 注解;又比如,需要被注入的依赖类提供的构造函数是带参数的,那么他的参数又怎么来呢?

@Module 正是帮我们解决这些问题的。参考 demo:3.3 节案例 B。

2.3 @Provides:

@Provides 用于标注 Module 所标注的类中的方法,该方法在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Inject 的变量赋值;

参考 demo:3.3 节案例 B。

2.4 @Component:

@Component 用于标注接口,是依赖需求方和依赖提供方之间的桥梁。被 Component 标注的接口在编译时会生成该接口的实现类(如果@Component 标注的接口为 CarComponent,则编译期生成的实现类为 DaggerCarComponent),我们通过调用这个实现类的方法完成注入;

2.5 @Qulifier:

@Qulifier 用于自定义注解,也就是说@Qulifier 就如同 Java 提供的几种基本元注解一样用来标记注解类。我们在使用@Module 来标注提供依赖的方法时,方法名我们是可以随便定义的(虽然我们定义方法名一般以 provide 开头,但这并不是强制的,只是为了增加可读性而已)。

那么 Dagger2 怎么知道这个方法是为谁提供依赖呢?答案就是返回值的类型,Dagger2 根据返回值的类型来决定为哪个被@Inject 标记了的变量赋值。但是问题来了,一旦有多个一样的返回类型 Dagger2 就懵逼了。@Qulifier 的存在正式为了解决这个问题,我们使用@Qulifier 来定义自己的注解,然后通过自定义的注解去标注提供依赖的方法和依赖需求方(也就是被@Inject 标注的变量),这样 Dagger2 就知道为谁提供依赖了。一个更为精简的定义:当类型不足以鉴别一个依赖的时候,我们就可以使用这个注解标示;

demo 参考:3.4 案例 C。

2.6 @Scope:

@Scope 同样用于自定义注解,我能可以通过@Scope 自定义的注解来限定注解作用域,实现单例(分局部和全局);

@Scope 需要 Component 和依赖提供者配合才能起作用,对于@Scope 注解的依赖,Component 会持有第一次创建的依赖,后面注入时都会复用这个依赖的实例,实质上@Scope 的目的就是为了让生成的依赖实例的生命周期与 Component 绑定

如果 Component 重建了,持有的@Scope 的依赖也会重建,所以为了维护局部单例需要自己维护 Component 的生命周期。

2.7 @Singleton:

@Singleton 其实就是一个通过@Scope 定义的注解,我们一般通过它来实现全局单例。但实际上它并不能提前全局单例,是否能提供全局单例还要取决于对应的 Component 是否为一个全局对象。

三 Dagger2 使用

3.1 引入 Dagger2

我们在使用时需要先添加依赖:

dependencies { api 'com.google.dagger:dagger:2.x' annotationProcessor 'com.google.dagger:dagger-compiler:2.x'}

添加完依赖后,我们由简入深一个个来介绍具体的使用。

3.2 案例 A

Car 类是需求依赖方,依赖了 Engine 类;因此我们需要在类变量 Engine 上添加@Inject 来告诉 Dagger2 来为自己提供依赖。 Engine 类是依赖提供方,因此我们需要在它的构造函数上添加@Inject

public class Engine { /** * Dagger2 通过@Inject 注解可以在需要这个类实例的时候来找到这个构造函数并把相关实例构造出来, * 以此来为被@Inject 标记了的变量提供依赖 * */ @Inject public Engine() { } @NonNull @Override public String toString() { return "Engine{}"; } public void run() { Log.i("tag", "引擎转起来了~~~ "); }

接下来我们需要创建一个用@Component 标注的接口 CarComponent,这个 CarComponent 其实就是一个注入器,这里用来将 Engine 注入到 Car 中。

@Componentpublic interface CarComponent { void inject(Car car);}

完成这些之后我们需要 Build 下项目,让 Dagger2 帮我们生成相关的 Java 类。接着我们就可以在 Car 的构造函数中调用 Dagger2 生成的 DaggerCarComponent 来实现注入(这其实在前面 Car 类的代码中已经有了体现)

public class Car { /** * @Inject:@Inject 有两个作用,一是用来标记需要依赖的变量,以此告诉 Dagger2 为它提供依赖 */ @Inject Engine engine; public Car() { DaggerCarComponent.builder().build().inject(this); } public Engine getEngine() { return this.engine; } public static void main(String ... args){ Car car = new Car(); System.out.println(car.getEngine()); }}

3.3 案例 B

3.3.1 @Module、@Provide 的使用

如果创建 Engine 的构造函数是带参数的呢?或者 Eggine 类是我们无法修改的呢?这时候就需要@Module 和@Provide 上场了。

可以看到下面 Engine 类的代码和上面的入门 demo 中的 Engine 代码几乎一样,只是多了个带参数的构造方法。

public class Engine { private String name; @Inject Engine(){} Engine(String name) { this.name = name; } @Override public String toString() { return "Engine{" + "name='" + name + '\'' + '}'; } public void run() { System.out.println("引擎转起来了~~~"); }}

接着我们需要一个 Module 类来生成依赖对象。前面介绍的@Module 就是用来标准这个类的,而@Provide 则是用来标注具体提供依赖对象的方法(这里有个不成文的规定,被@Provide 标注的方法命名我们一般以 provide 开头,这并不是强制的但有益于提升代码的可读性)。

@Modulepublic class MarkCarModule { String engineType; public MarkCarModule(String engineType) { this.engineType = engineType; } @Provides Engine provideEngine() { return new Engine(engineType); }}

接下来我们还需要对 CarComponent 进行一点点修改,之前的@Component 注解是不带参数的,现在我们需要加上 modules = {MarkCarModule.class},用来告诉 Dagger2 提供依赖的是 MarkCarModule 这个类。

@Component(modules = MarkCarModule.class)public interface CarComponent { void inject(Car car);}

Car 类的构造函数我们也需要修改,相比之前多了个 markCarModule(new MarkCarModule())方法,这就相当于告诉了注入器 DaggerCarComponent 把 MarkCarModule 提供的依赖注入到了 Car 类中。

public class Car { @Inject Engine engine; public Car() { DaggerCarComponent.builder().markCarModule(new MarkCarModule("国产发动机")) .build().inject(this); } public Engine getEngine() { return this.engine; } public static void main(String ... args){ Car car = new Car(); System.out.println(car.getEngine()); }}

这样一个最最基本的依赖注入就完成了,接下来我们测试下我们的代码。 输出:

Engine{name='国产发动机'}

3.3.2 Dagger2 的依赖查找顺序说明

我们提到@Inject 和@Module 都可以提供依赖,那如果我们既在构造函数上通过标记@Inject 提供依赖,又通过@Module 提

最低0.47元/天 解锁文章

优惠劵

蔚1

关注

关注

11

点赞

51

收藏

觉得还不错?

一键收藏

知道了

7

评论

神兵利器Dagger2一站式全解(详细总结)

Dagger2是一款基于Java注解来实现的完全在编译阶段完成依赖注入的开源库,主要用于模块间解耦、提高代码的健壮性和可维护性,github 的star数15k,应用广泛。这篇 Chat 主要介绍 Dagger2 从起源、基础,到使用、进阶,再到场景、原理的详细分析总结。文章适合人群:对Dagger2框架感兴趣,有意向java/Android高级开发进步的开发者。Chat 主要内容有:Da...

复制链接

扫一扫

dagger2 视频

11-29

dagger2 视频 dagger2 视频 dagger2 视频 dagger2 视频

架构进阶,Dagger2的原理及使用详解

weixin_44339238的博客

08-14

206

目录

一:Dagger2是什么?

二:为什么要有Dagger2

三:Dagger2如何使用

基本的概念

如何使用Dagger2

高级用法

(1)构造方法需要其他参数时候

(2) 模块之间的依赖关系

(3) @Named注解使用

(4) @Singleton注解

(5)自定义Scoped

(6)Subcomponent

(7)lazy 和 Provider

四: MVP + Dagger2...

7 条评论

您还未登录,请先

登录

后发表或查看评论

Dagger2 到底能为我们做些什么?(大厂都在用的秘密?)

半身风雪

04-27

1435

在文章开始之前,我们先来了解一下什么是Dagger2大厂 公司用的非常多是原来由程序代码中主动获取的资源,转变由第三方获取并使原来的代码被动接收的方式,以达到解耦的效果,称为控制反转。这里来张图哈,说白了,IOC 就相当于一个保姆,你想要干哈,直接告诉保姆呗

下面我们看张生活中的图:很简单的一张图呢,我们买了商品,商品经过打包,快递员拿到包裹,直接送到你的手上。 整个流程是不是清晰了很多呢?㊀

总结

看了上面的代码,有没有发现,代码简单了很多呢?我们告别了传统 的代码,大大的降低

Dagger2从入门到放弃再到恍然大悟

CreativeBoy的专栏

05-29

1万+

现在Dagger2在项目里用的越来越多了,最近花了些时间学习了一下Dagger2,这篇文章主要帮助理解Dagger2的注入实现过程,如有错误,还请指正!什么是Dagger2Dagger2是Dagger的升级版,是一个依赖注入框架,现在由Google接手维护。 恩,这里有个关键字依赖注入,因此我们得先知道什么是依赖注入,才能更好的理解Dagger2。依赖注入是面向对象编程的一种设计模式,其目的是为了降

google四件套之Dagger2。从入门到爱不释手,之:Dagger2基础知识及在Java中使用(2)

岩浆李的游鱼

09-04

414

前言

网上都说Dagger2是比较难上手的,我在看了大量资料和使用时也遇到了很多不懂或者模糊的知识点,而且大部分博客资料都比较古老。突然有那么一瞬间,突然明白了所以然,故总结了3篇文章。话说在java中使用还是很繁琐的,不要怕带你真正上手,并运用到我们的Android项目中去。

本次Dagger2讲解总共分4篇:

1、Dagger2基础知识及在Java中使用(1)

2、Dagger2基础知识及在J...

将Android进行到底之Dagger2(一)

知识应该共享,创造才应收费

08-07

1855

当前我们开发软件大多都是使用面向对象的思想。将我们想要操作的对象抽象成类,使用的时候再根据类实例化出我们想要操作的对象,再通过对这些对象的管理和组合操作,最终形成咱们想要的软件。而一个软件是否优秀就取决于对组成软件对各个对象的管理和组合是否合理。各个对象之间的耦合度是否足够低。而这些可以使用dagger2和hilt这类的依赖注入框架很好的实现低耦合的软件系统............

Dagger2 的使用与基本原理

tmacfrank的博客

10-30

331

使用 Dagger2 的最佳做法:如果有可能,通过@Inject进行构造函数注入,以向 Dagger 图中添加类型。使用@Binds告知 Dagger 接口应采用哪种实现使用@Provides告知 Dagger 如何提供你的项目所不具备的类只能在组件中声明一次模块根据注释的使用生命周期,为作用域注释命名,例如和依赖注入。

Android开源框架--Dagger2详解

最新发布

袁震的博客

11-28

1203

功名只向马上取,真是英雄一丈夫

Dagger2的简单使用

你全家都是博客

04-02

193

Dagger2可以更好的帮助我们解耦 不用担心对象或者属性在被生命周期持有导致的未释放

为什么要用Dagger2 举个例子

一般正常调用一个对象的方法是这样

public class A {

public void eat() {

System.out.print("吃饭了");

}

}

A a = new A();

a.eat();

改为在A类传入对象B是这样

public class A {

private B b;

public A...

详细的Dagger2+MVP融合,一行一行分析,一点一点进步

02-25

详细的Dagger2+MVP融合,一行一行分析,一点一点进步源码

用Dagger2在Android中实现依赖注入

02-25

依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的。使应用开发更加可扩展,更容易维护。通过本文你会学到如何使用Dagger2来处理依赖。如果以对象需要另外的一个对象才能完成一个完整功能的话,那么这里就存在一个依赖。比如,悟空要用金箍棒才能三打白骨精,要筋斗云才能十万八千里。悟空有对金箍棒和筋斗云的依赖。你可以在悟空对象里初始化金箍棒,也可以用一个工厂方法批量生产金箍棒。使用依赖注入可以无需一个专门的类来初始化这些依赖对象。这样就实现了解耦。本教程会使用最新的Dagger2(当前的版本是2.2)。这里是官网。你可以在这里找到最新的发布。AndroidStudio是必须的。

Dagger 2 完全解析(三),Component与SubComponent

xiaowu 专栏

06-26

2292

Dagger 2 Component 与 SubComponent

Dagger 2 完全解析(一),基本使用与原理

Dagger 2 完全解析(二), 进阶使用

Dagger 2 完全解析(三), Component 与 SubComponent

本系列文章是基于 Google Dagger 2.23.2 版本, Kotlin 1.3.21版本

理解前面两篇文章后,可以使用 Dagge...

告别Dagger2模板代码:Dagger Android使用详解

热门推荐

却把清梅嗅的博客

08-22

2万+

概述,学Dagger2-Android的理由Dagger2的窘境在使用Dagger2进行Android开发时,不可避免的问题是我们需要实例化一些Android系统的类,比如Activity或者Fragment。最理想的情况是Dagger能够创建所有需要依赖注入的对象,但事实上,我们不得不在容器的声明周期中声明这样的代码:public class FrombulationActivity extend

Dagger2基本使用与原理

fan_zyf的博客

05-12

8843

上一篇介绍了Dagger2的一些注解点击打开链接

一、Dagger2的一些简单配置

1.在build.gradle(project..)中添加apt插件

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

2.在build.gradle(Module:app)中添加如下代码,应用apt插件

apply plugin: 'c

Android Dagger2 MVP架构 一看就明白

Lincoln 的专栏

08-15

1万+

Dagger2 在 MVP 架构中的使用,希望能够帮助到学习Dagger2的童鞋……

dagger2使用方法教程之简明讲解

01-04

前言

Dagger 这个库的取名不仅仅来自它的本意“匕首”,同时也暗示了它的原理。Jake Wharton 在对 Dagger 的介绍中指出,Dagger 即 DAG-er,这里的 DAG 即数据结构中的 DAG——有向无环图(Directed Acyclic Graph)。也就是说,Dagger 是一个基于有向无环图结构的依赖注入库,因此Dagger的使用过程中不能出现循环依赖。

Android开发从一开始的MVC框架,到MVP,到MVVM,不断变化。现在MVVM的data-binding还在实验阶段,传统的MVC框架Activity内部可能包含大量的代码,难以维护,现在主流的架构还是使用M

Dagger2中Scope使用Demo

08-15

Dagger2中@Scope注解的使用,详见博客http://blog.csdn.net/u012702547/article/details/52213706

详解 Dagger2 的 @Scope 和 @Subcomponent

joker

11-26

2586

个人觉得网上关于 dagger2 文章中关于 @Scope 和 @Subcomponent 解释的并不是很详细,也可能是我个人能力有限不能够理解,所以写下这篇文章,希望能够帮助后人更方便的入门。

@Scope 是什么

@Scpoe 的使用

@Subcomponent 是什么

@Subcomponent 的使用

@Subcomponent 和 @Component 的实际使用场景定义

@Scope 是

Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料

weixin_30293135的博客

07-14

255

我是曹新雨,我为自己代言。现在的菜鸟,3年以后我就是大神。为自己加油。微信:aycaoxinyu

Dragger2是什么,我就不再说了。资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精挑细选,一般的文章我是不推荐的。

http://android.jobbole.com/82694/

http://android.jobbole.com/8270...

Android Dagger2 的用法

06-13

Dagger2 是一个依赖注入框架,它的作用是将依赖关系的创建和管理,从业务逻辑中解耦出来。在 Android 中使用 Dagger2 可以解决代码耦合度高、可测试性差等问题。 下面是 Dagger2 的用法: 1. 在 build.gradle 中...

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

非常没帮助

没帮助

一般

有帮助

非常有帮助

提交

蔚1

CSDN认证博客专家

CSDN认证企业博客

码龄15年

暂无认证

4825

原创

4424

周排名

50万+

总排名

899万+

访问

等级

6万+

积分

1万+

粉丝

6827

获赞

2005

评论

3万+

收藏

私信

关注

分类专栏

后端

3篇

达人课

31篇

Chat文章

15篇

极客书

2篇

区块链

人工智能

19篇

数据库

2篇

游戏

1篇

Python

15篇

前端框架

4篇

物联网

3篇

程序人生

12篇

Linux

5篇

算法

6篇

大数据

5篇

架构

2篇

DDD

1篇

Vue

1篇

Webpack

1篇

JavaScript

1篇

最新评论

Kali Linux:用永恒之蓝对 Windows 7 进行渗透并揭密勒索病毒攻击方法

jdxpalc12:

没有一点格局把格局打开嘛

大白话 5 分钟带你走进人工智能:神经网络之反向传播详细案例及解释

mayi0130:

图片看不到,可以发原文地址链接吗

计算机究竟是怎么跑起来的

Jammy2021:

图看不到

[OS X軟件] 我一直在用的 司机会看的那种 免费资源又多

weixin_58723136:

大神,还有这个资源链接吗?打不开啊

针对运营商行业的虚拟化应用性能监测管理解决方案

lazen:

有这么牛的产品啊?是哪家的产品呢?

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

吃透 Spring Boot + Netty , 还开发不了通讯系统?

瞧,工程师绘图最佳实践!

Spring Boot 2.3 支持分层 Jar 包、优雅停机、完美支持 Docker/k8s 了

2022年1篇

2020年1387篇

2019年1882篇

2018年1561篇

目录

目录

分类专栏

后端

3篇

达人课

31篇

Chat文章

15篇

极客书

2篇

区块链

人工智能

19篇

数据库

2篇

游戏

1篇

Python

15篇

前端框架

4篇

物联网

3篇

程序人生

12篇

Linux

5篇

算法

6篇

大数据

5篇

架构

2篇

DDD

1篇

Vue

1篇

Webpack

1篇

JavaScript

1篇

目录

评论 7

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

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

余额充值

WPS公式如何打出dagger? - 知乎

WPS公式如何打出dagger? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册WPS Office编辑 WPSwps2019金山WPSWPS公式如何打出dagger?就是产生算符中的那个dagger [图片]显示全部 ​关注者4被浏览8,843关注问题​写回答​邀请回答​好问题​添加评论​分享​3 个回答默认排序麦小兜致力于办公自动化​ 关注在 WPS 公式中,可以使用下面的方法打出 dagger 符号:1. 在公式编辑器中,将光标放置在要插入 dagger 符号的位置。2. 点击公式编辑器工具栏中的“符号”按钮,打开符号面板。3. 在符号面板中,选择“其他符号”选项卡。4. 在符号列表中,找到 dagger 符号,并点击它。5. 点击“插入”按钮,将 dagger 符号插入到公式中。另外,你也可以使用 dagger 符号的 LaTeX 命令 "\dagger" 来插入 dagger 符号。在公式编辑器中,输入“\dagger”,然后按下空格键或回车键即可将其转换为 dagger 符号。发布于 2023-05-02 07:36​赞同 1​​添加评论​分享​收藏​喜欢收起​李长虎​ 关注编辑于 2023-04-26 07:19​赞同 2​​1 条评论​分享​收藏​喜欢收起​​