‡£犀利团购请问团购怎么退款款‡£能不能办退款‡£

后使用快捷导航没有帐号?
查看: 1904|回复: 4
黑色匕首Dagger 80W主机使用评测
TA的每日心情开心 14:06签到天数: 48 天[LV.5]常住居民I巴士币帖子主题
赞助论坛或者有急事可以联系小豪 QQ
P.jpg (97.83 KB, 下载次数: 0)
16:50 上传
大家好,我是蒸汽烟爱好者Vape豪,很高兴跟大家见面。自从进入2016年,单电池主机的输出性能和尺寸外观的变化不断改变着我们对它们的认识,如今单电池主机不再是简单的“入门级”设备。今天评测的主角Dagger 80W主机,便是一款体形小巧而又拥有不俗的输出表现的设备,具体的使用体验如何,下面就让小豪为大家细细道来。
P.jpg (90.27 KB, 下载次数: 0)
16:50 上传
P.jpg (139.79 KB, 下载次数: 0)
16:50 上传
Dagger80W主机采用抗压纸筒包装,包装风格很bigger,也保证了主机在运输中的安全。Dagger主机支持时下比较流行的面板更换功能,不论是主机自带的黑色碳纤维面板还是官方推出的其他面板,看起来都非常不错,与主机搭配起来颜值很高。更换贴片的方式比较简单,我们可以使用绕线棒或是螺丝刀从主机的两侧开孔将面板顶开,进行更换,面板均为软磁贴片,与主机的贴合度非常高,完全不会晃动。
P.jpg (143.67 KB, 下载次数: 0)
16:50 上传
作为一款单电池主机,Dagger的尺寸也是十分小巧,通过比较可以看出,Dagger的尺寸与克莱鹏X3主机很相似,在宽度上Dagger会比X3稍宽。Dagger主机整体采用锌合金材料,拿在手里虽然小巧,但是会有种短暂的压手感,因为Dagger可能会超出我们对它体重上的猜测,整机的漆面摸上去很细腻,在使用过几天后并没有出现划痕和掉漆的问题。
P.jpg (118.72 KB, 下载次数: 0)
16:50 上传
P.jpg (89.56 KB, 下载次数: 0)
16:50 上传
得益于与DIY80主机相同的“翻盖式”的电池盖设计,Dagger主机的尺寸得到了很好的控制,整机表面没有任何的LOGO和图标,而厂家很别出心裁的将DAGGER的LOGO做在了电池盖内侧,不但让电池仓看起来没那么LOW,在机器的整体颜值上也有所增色。主机顶部的进气开槽与液体导出槽的设计非常美观,两条线刚好组成了匕首尖端的样子,与主机的名称和LOGO遥相呼应。
P.jpg (139.38 KB, 下载次数: 0)
16:50 上传
Dagger主机在操作上十分简单,三下点火键可以对主机进行锁定,五下点火键便可以在各个模式之间切换,长按点火键进行选择。主机拥有BYPASS,TCR,AC温控等模式,整体功能十分全面,最低支持电阻为0.08欧姆。温控模式下,Dagger主机可以通过长按点火键在各项子功能之间进行确认,在TCR数据调整时可以完全通过主机进行设置,十分简单。由于点火键在功能上的叠加与相应速度较高,在使用五下点火键进行模式切换时,有很大几率会出现五响应的问题,在进行此类操作时,需要注意“点击”速度与力度的控制,确保五次点击全部被主机接收才能正常切换模式。
P.jpg (142.43 KB, 下载次数: 0)
16:50 上传
P.jpg (105.92 KB, 下载次数: 0)
16:50 上传
Dagger主机的AC温控模式与克莱鹏X3主机的AUTO温控模式很相似,在此模式下主机可以自动匹配一个适合的输出功率或者焦耳数值,对于新手来说,这确实是一个非常实用的功能。在进入AC温控模式之前,需要通过加减键同时按住,对雾化器电阻进行精确测定,否则会出现不工作或者干烧误报的情况。Gagger主机的AC温控与X3主机的AUTO温控模式略有区别,在AC温控模式下Dagger主机不可以进行任何调节,而X3主机可以对温度进行调节。同时在功率模式,Dagger主机也可以通过加减键对阻值进行精确检测,这里建议大家可以在更换雾化器或者切换模式之后都对雾化器电阻进行一次检测,这样可以保证我们在数据调整时更加精准。
P.jpg (112.75 KB, 下载次数: 0)
16:50 上传
Dagger主机在连接电脑后可以选择充电与数据连接模式,在选择数据连接模式后,我们可以通过官方的Reekbox软件,对主机的开机画面进行自定义,同时还可以对主机的系统进行升级和维护,相信在之后,官方会推出更多的开放性功能,让Dagger主机的可玩性更高。?片,与主机的贴合度非常高,完全不会晃动。
IMG_959.jpg (139.02 KB, 下载次数: 0)
16:50 上传
OK,Dagger 80W主机的评测就到这里,简单的为大家总结一下这款设备的优缺点吧。优点:1.外观小巧,做工与设计十分优秀,可更换面板,彰显个性。& && &2.点火响应速度快,输出稳定性很高。& && &3.AC温控模式对于新手接触温控模式来说十分简单。缺点:1.模式切换时会有误操作与不响应情况出现,需要注意点火键的点击力度与速度。& && &2.体形虽小,但是重量稍微有些大,有些压裤兜的感觉。总体来说,Dagger 80W主机小巧的身材会很方便用户出门携带,整体的颜值做工也不会丢面子,在输出能力上也是可圈可点,而操作与重量上的不足就要看各位的取舍了,希望小豪的评测可以给大家一定的参考。
我是Vape豪,本文由我原创,转载务必注明作者及出处,如有疑问请联系QQ。如果你也是电子烟玩家,欢迎到蒸汽巴士投稿,这里是最权威的电子烟媒体评测网站,这里有没有广告却很有聊效的论坛,最火爆的活动和福利,你还在等什么,快来加入我们吧!
(137.13 KB, 下载次数: 0)
16:50 上传
点击分享到:
我是Vape豪,欢迎各位加入蒸汽巴士,有急事可以加QQ联系我!
TA的每日心情擦汗昨天&13:40签到天数: 247 天[LV.8]以坛为家I巴士币帖子主题
用心的人都是大神
很不错的设备,尤其是温控,很给力
TA的每日心情开心昨天&00:29签到天数: 359 天[LV.8]以坛为家I巴士币帖子主题
哇,这个机器真是挺酷的,颜值很高啊
TA的每日心情开心 16:00签到天数: 112 天[LV.6]常住居民II巴士币帖子主题
金牌会员, 积分 1459, 距离下一级还需 1541 积分
金牌会员, 积分 1459, 距离下一级还需 1541 积分
黑色,无敌的帅!
该用户从未签到巴士币帖子主题
新手上路, 积分 9, 距离下一级还需 41 积分
新手上路, 积分 9, 距离下一级还需 41 积分
我这个是dagger吗?但好像看起来不太一样啊
(12.78 KB, 下载次数: 0)
02:54 上传
&|||||||||
Powered by Discuz! X3.2. Theme By Yeei!Dagger2 使用正确姿势 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了25671字,被238人关注,获得了278个喜欢
Dagger2 使用正确姿势
Dagger2 使用正确姿势
上一篇文章《》中介绍了Dagger2的一些显浅的使用方式,我觉得是非常适合入门Dagger2的傻瓜式讲解,后来发现有些内容讲的不够仔细,有些细节没有详细解释清楚。参考了以下三篇文章后,对之前的内容进行一些补充。
以上这三篇文章对于Dagger2的思路理得很清晰,并且对于Dagger2做出了一个抽象的概念讲解,本文的一些内容也是摘自以上文章。
没有看过《》可能不利于阅读
本文的内容:
本篇的内容同样不涉及到Dagger2的内部原理,只是对上一篇文章做了一些知识的补充,从而能够更好的使用Dagger2
理清思路,Dagger2的两种提供注入实例的方式
为什么ActivityComponent要提供一个inject方法。
Scope的使用,如何实现单例?
Qualifier限定符的作用以及使用。
理清思路,Dagger2的两种提供注入实例的方式。
之前说的是提供注入实例的方式是通过编写Moudle,并且提供一些provideXXX()的方法,然后通过Component把这些对象进行注入。其实在Dagger2中还有一种方式实现对象的注入,这种方式比较简单。假设我们需要注入一个A类的对象,我们只需要在A类的构造函数中添加@Inject注解即可,然后在Component中直接提供一个方法获取A的实例就行了。代码如下:
public class A{
public A(){
XXXComponent 中
然后在我们需要注入A对象的地方(Activity),使用Component调用getA()方法即可获得这个A对象。
说到这里,可能也会有些疑问,这里的A类是一个简单的对象,假如A需要在构造函数传入参数怎么办?其实原理和上一篇文章说的差不多,这些参数会根据依赖的Component或者当前Component的module中提供的provideXXX()方法来获取。
这里的Dagger2总共就有这两种方式提供依赖的注入。事实上,经过测试,Dagger2在遇到@Inject修饰的成员变量的时候,会先查找Component中是否有提供对象,找不到的情况下,才会去找包含有@Inject的构造函数。
整个Dagger2的依赖注入的过程如下:
步骤1:查找Module中是否存在创建该类的方法。
步骤2:若存在创建类方法,查看该方法是否存在参数
步骤2.1:若存在参数,则按从**步骤1**开始依次初始化每个参数
步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
步骤3:若不存在创建类方法,则查找Inject注解的构造函数,
看构造函数是否存在参数
步骤3.1:若存在参数,则从**步骤1**开始依次初始化每个参数
步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
为什么ActivityComponent要提供一个inject方法
首先经过我的测试,当我在DaggerActivity中对对某些需要注入的成员添加@Inject注解的时候,Dagger2就会生成一个DaggerActivity_MembersInjector的东西,这个是对成员变量进行注入的关键类,涉及到一些比较深入的内容,我们这里先不要深入探讨这里的运行机制。我们只需要知道当我们需要注入一些成员变量的时候,我们需要在ActivityComponent中提供一个方法:
void inject(DaggerActivity daggerActivity);
并且在初始化的时候调用这个方法,才能成功注入。至于这个方法inject是官方推荐的名称,我们可以不用这个,但是使用inject的话比较好理解吧。值得注意的一点是,这个方法的参数一定要准确,比如DaggerActivity需要注入,我们这里就需要些DaggerActivity,不能写成BaseActvity或者Activity,否则会注入失败。因为内部的原理是要对这个参数进行注入的,很显然在DaggerActivity中需要注入的内容在BaseActivity或者Activity中并不存在。
Scope的使用,如何实现单例?
这个迷之Scope也是有点难以理解,我们在哪里使用到了Scope呢。在我们的AppComponent中添加了一个注解为@Singleton,@Singleton就是一个Scope,据说可以实现单例哟。。。难道这样就实现了单例模式?我刚刚开始是这样理解的。直到仔细的看了几遍我才知道并不是这样的。
事实上@Sinleton中并没有创建单例的能力,那么AppComponent中提供的依赖注入是如何实现单例的呢。其实这个原理很贱单。
首先Module提供了创建实例的方法,接着AppComponent中对Module进行管理,最后AppComponent在自定义Applicaiton中被实例化了一次。
这个实例化了一次是最重要的呀。仅仅被实例化了一次,那不就是单例么。就是这么简单呀。
可能有些童靴当时就不乐意了,那既然这样都已经实现了单例,那么这个@Singltop还要来何用?不是多此一举吗。
其实@Singletop还有有一些作用的,首先一方面能让你直面的了解到这是一个单例,其次这个@Singletop能够更好的管理Modlue和Component之间的关系。
Dagger2需要保证Component和Module是匹配的,就需要用到这个注解。
为什么这样说,看过上一篇文章的人就会知道,我定义了一个ActivityScope,我之前的解释是说ActivityScope是为了对应Activity的生命周期(当时就很不理解,难道这个Scope真的这么有魔性,声明一个ActivityScope就能让提供的注入对象和Activity生命周期一致),很显然,这是错误的。为什么需要这个Scope呢?原因是因为我在AppComponent中是有@Singletop的,ActivityComponent中依赖了AppComponent,所以我们需要使用一个Scope来匹配他们之间的关系,不然就会在编译期间报错。并不是说ActivityScope能让实例和Activity生命周期一致。和Activity生命周期一致是因为ActivityComponent是在Activity中生成实例的。(具体Dagger2内部是如何保障这个的,并没有深入研究过)。
Qualifier 限定符的作用以及使用。
这也是一个很强大的注解,首先为什么需要用这么一个东西呢,之前说道过,在Module中的provide方法实际上是根据返回值来进行识别的。但是假设我需要根据不同的需求传入不同的构造参数的时候,如何区分呢?比如:一个Presenter,可能他有两个构造函数,分别对应不同的需求,这种情况下,provide方法的返回值都是Presenter,那么就需要使用Qualifier。具体怎么使用呢。
首先声明一个注解用@Qualifier修饰,然后在需要区别的地方添加就行了,下面是一个实例代码:
public class AppModule {
private final A
public AppModule(App app) {
this.app =
@Singleton
@ForApplication
Context provideAppContext() {
@Singleton
Prefser providePrefser(@ForApplication Context context) {
return new Prefser(context);
@Singleton
AccountManager provideAccountManager(@ForApplication Context context) {
return AccountManager.get(context);
首先在provide中添加一个注解@ForApplicition,接着在需要使用这个Context的地方再次标示即可。这样假设有其他一些提供了Activity的Context的地方和这里发生冲突的时候,Dagger2也能准确找到这个Applicaiton的Context。
这里对Dagger的总体使用方式进行了一些补充,还有没有从源码的角度来理解Dagger2,下篇文章会结合Dagger2生成的代码进行讨论,只有认识了这个运行机制,我们才能运用得得心应手。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
如果你是程序员,或者有一颗喜欢写程序的心,喜欢分享技术干货、项目经验、程序员日常囧事等等,欢迎投稿《程序员》专题。
专题主编:小...
· 242711人关注
玩转简书的第一步,从这个专题开始。
想上首页热门榜么?好内容想被更多人看到么?来投稿吧!如果被拒也不要灰心哦~入选文章会进一个队...
· 142817人关注
本专题仅让编辑在特殊情况下使用,入选文章将立刻上首页。绕过推荐队列。
使用场景:
- 突发事件的相关内容,需要立刻推首页
· 20412人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:Dagger 2 和 DataBinding 一起使用发生冲突的解决方法 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了308字,被3人关注,获得了3个喜欢
Dagger 2 和 DataBinding 一起使用发生冲突的解决方法
最近在学习Dagger 2,所以准备把加进以前一个项目中并且达到学习的目的,但是在和DataBinding一起使用时会报一下错:
而单独使用DataBinding 是不会报错,这是改正错误之前的gradle文件:
因为这种情况以前没遇见过,所以只能google了,在下面两篇文章找到解决解决办法就是将在gradle里apt插件注释掉,并将dependencies下编译dagger2库
apt 'com.google.dagger:dagger-compiler:2.0.2'改为provided 'com.google.dagger:dagger-compiler:2.0.2'
这样编译便不会出错了。
感谢提出的问题,上面的办法确实解决application编译不会报错,但却无法使用apt插件库,而Dagger 2需要apt插件库的支持。
不需要注释apt插件库,只需将apt插件库依赖版本从classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'更新到classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'即可,这种方法经过我测试编译后是没问题。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:Dagger2解惑 - 推酷
Dagger2解惑
最近一直在关注Android项目开发中的整体架构设计问题,
如何在复杂的业务逻辑和日益膨胀的功能需求面前保持项目架构的稳定
是一个很值得深入学习的问题。前段时间看到开发社区里有不少人在推崇
Dagger2 + MVP
模式来构建整体项目框架,MVP模式之前在项目中有使用过,MVP虽然从Activity和Fragment中抽离出了业务逻辑层,但是也不能完全解耦代码。
而Dagger2的出现正好解决了这一问题,这里不谈Dagger2的使用方法,主要是分享下Dagger2的工作原理和使用中遇到的一些疑惑。
Dagger2的工作原理
用过Dagger2的同学都知道,只要通过几个注解、Component、Module就可以实现依赖注入,再也不用写
了,简直太神奇了。下面就让我们揭开Dagger2神秘的面纱,看看它到底是怎么工作的
@Singleton@Component(modules = ApplicationModule.class)public interface ApplicationComponent { @ApplicationContext
Context context();
ApiService apiService();
DataManager dataManager();}
@Modulepublic class ApplicationModule {
private final Application mA
public ApplicationModule(Application application) {
mApplication =
@ApplicationContext
Context provideContext() {
@Singleton
ApiService provideApiService() {
return new ApiService();
@Singletonpublic class DataManager { private ApiService mApiS
public DataManager(ApiService apiService) {
mApiService = apiS
上面代码主要有三部分组成,
ApplicationComponent、ApplicationModule、DataManager(ApiService是其中一个成员变量)
在编译时,Dagger2会自动生成
ApplicationComponent
DaggerApplicationComponent
@Generated(&dagger.ponentProcessor&)public final class DaggerApplicationComponent implements ApplicationComponent {
// 在ApplicationModule中使用@Providers注解标识
private Provider&Context& provideContextP
// 在ApplicationModule中使用@Providers注解标识
private Provider&ApiService& provideApiServiceP
// DataManager是通过@Inject注解标识在构造函数上的隐式Provider
private Provider&DataManager& dataManagerP
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
initialize(builder);
public static Builder builder() {
return new Builder();
private void initialize(final Builder builder) {
// 这里contextProvider实现类是ApplicationModule_ProvideContextFactory,
// 而这个工厂中实际使用的是ApplicationModule
this.provideContextProvider = ApplicationModule_ProvideContextFactory .create(builder.applicationModule);
// 由于ApplicationModule中provideApiService()方法用了@Singleton作用域标识,
// 所以区别于contextProvider,它用了ScopeProvider来包装了一下,
// 通过查看ScopeProvider源码可以看出,它其实是把
// ApplicationModule_ProvideApiServiceFactory封装了一下,
// 当其未实例化时从factory中get一个实例出来保存其中并返回给调用者,
// 而当它已经实例过下次再调用时,就不会再从factory中get而是直接返
// 回之前保存的实例对象
this.provideApiServiceProvider = ScopedProvider
.create(ApplicationModule_ProvideApiServiceFactory
.create(builder.applicationModule));
// dataManagerProvider有别于apiServiceProvider,
// 前者是通过构造函数提供的隐式provider,
// 而后者是通过ApplicationMoudule用@Provider注解显示提供的provider,
// 两者没有本质上的区别,只是写法上的不一样
this.dataManagerProvider = ScopedProvider
.create(DataManager_Factory.create(provideApiServiceProvider));
public Context context() {
// 这里实际调用的是applicationModule.provideContext()方法
return provideContextProvider.get();
public ApiService apiService() {
// 这里实际调用的是applicationModule.provideApiService()方法
return provideApiServiceProvider.get();
public DataManager dataManager() {
// 这里实际调用的是new DataManager(provideApiServiceProvider.get())
return dataManagerProvider.get();
// 这里的Builder类就是暴露给外部代码使用的,
// 通过该Builder传入Component的依赖和Module,并通过build()方法实例Component
public static final class Builder {
private ApplicationModule applicationM
private Builder() {
public ApplicationComponent build() {
if (applicationModule == null) {
throw new IllegalStateException(&applicationModule must be set&);
return new DaggerApplicationComponent(this);
public Builder applicationModule(ApplicationModule applicationModule) {
if (applicationModule == null) {
throw new NullPointerException(&applicationModule&);
this.applicationModule = applicationM
return this;
从上面的代码可以看出
ApplicationComponent
构建了一系列
最后在对象注入时使用的,来看下一下代码
@PerActivity@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)public interface ActivityComponent {
void inject(MainActivity activity);}
@Modulepublic class ActivityModule {
private final Activity mA
public ActivityModule(Activity activity) {
mActivity =
@ActivityContext
Context providesContext() {
public class MainActivity extends BaseActivity { @Inject
DataManager mDataM
ActivityComponet
ApplicationComponent
,所以它可以获得
ApplicationComponent
构建的一系列Provider,
MainActivity
是需要注入的对象,最终
MainActivity.mDataManager
变量会被注入赋值
@Generated(&dagger.ponentProcessor&)public final class DaggerActivityComponent implements ActivityComponent { private Provider&DataManager& dataManagerP private MembersInjector&MainActivity& mainActivityMembersI
private void initialize(final Builder builder) {
// 从这里可以看出dataManagerProvider实际调用的是
// applicationComponent.dataManager()
this.dataManagerProvider = new Factory&DataManager&() {
@Override public DataManager get() {
DataManager provided = builder.applicationComponent.dataManager();
if (provided == null) {
throw new NullPointerException(&Cannot return null from a non-@Nullable component method&);
// 这里是创建了MainActivity注入器,
// 目的是为MainActivity中用@Inject注解标识的成员变量注入实例
this.mainActivityMembersInjector = MainActivity_MembersInjector
.create((MembersInjector) MembersInjectors.noOp(),
dataManagerProvider);
public void inject(MainActivity activity) {
// 当在外部调用该方法时,实际是为mDataManager赋值了,等同于 // activity.mDataManager = dataManagerProvider.get();
mainActivityMembersInjector.injectMembers(activity);
Dagger2的那些坑
分析完Dagger2的工作原理后,让我们来看看在实际使用过程中会遇到哪些坑
component 的 inject 函数不要声明基类参数
MainActivity
SettingActivity
都是继承于
BaseActivity
,那么在注入时只能指定
MainActivity
SettingActivity
,而不能想当然的使用基类
BaseActivity
,这样子类是不会被注入的。这样就会带来一个问题,如果说我们很多的Activity都需要注入,那么在
ActivityComponet
中我就需要这么写(是不是很蛋疼 ~_~!!!)
void inject(MainActivity activity);void inject(LoginActivity activity);void inject(RegisterActivity activity);void inject(AccountAuthActivity activity);void inject(UserInfoEditActivity activity);void inject(UserStatusActivity activity);void inject(UserBindRescuerActivity activity);......
Scope 注解必须用在 module 的 provide 方法上,否则并不能达到局部单例的效果
如果 module 的 provide 方法使用了 scope 注解,那么 component 就必须使用同一个注解,否则编译会失败
如果 module 的 provide 方法没有使用 scope 注解,那么 component 和 module 是否加注解都无关紧要,可以通过编译,但是没有局部单例效果;
对于直接使用 @Inject 构造函数的依赖,如果把 scope 注解放到它的类上,而不是构造函数上,就能达到局部单例的效果了;
至此,Dagger2的整个注入流程我们就分析完了,其实也不算复杂,只是使用了大量的设计模式,分析代码时跳来跳去的容易把人搞晕。Dagger2的出现是解耦了代码,但是同时也带来了其它的一些问题,比如:引入大量Component后期
管理、维护就很非常困难
Component划分粒度问题
当业务逻辑存在重复或者相似性时如何重用Component
等等,这些都是需要进一步学习和思考。
欢迎大家拍砖
原创不易,欢迎转载,但还请注明出处:
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Dagger2使用 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了30468字,被1892人关注,获得了1560个喜欢
Dagger2使用
在简单使用了一段时间的dagger2之后,来谈谈对dagger2浅薄的认知。
首先,使用依赖注入可以带来哪些好处?
1、依赖的注入和配置独立于组件之外,注入的对象在一个独立、不耦合的地方初始化,这样在改变注入对象时,我们只需要修改对象的实现方法,而不用大改代码库。
2、依赖可以注入到一个组件中:我们可以注入这些依赖的模拟实现,这样使得测试更加简单。
3、app中的组件不需要知道有关实例创建和生命周期的任何事情,这些由我们的依赖注入框架管理的。
我觉得,dagger2这样的依赖注入框架对MVP架构来说,是最好的解耦工具,可以进一步降低modle-view-presenter之间的耦合度。所以,如果你的项目在使用MVP架构开发,强烈建议配合dagger2一起使用。
接下来,在贴代码之前,我先说说明下我的MVP架构和传统的MVP有些不同,传统MVP的M层处理业务逻辑,P层仅仅是V和M的桥梁;而我的P层同时处理与model相关的业务逻辑,不处理View层次的逻辑,View层次的逻辑交给V自己处理,M层仅仅是bean,这种方式是根据开发中的实际情况而作的考虑,这里先不作讨论。
先看结构图:
接下来,分解这张图:AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
Context context();
// 提供Applicaiton的Context
ThreadExecutor threadExecutor();
ApiService apiService();
// 所有Api请求的管理类
SpfManager spfManager();
// SharedPreference管理类
DBManager dbManager();
// 数据库管理类
AppModule: 这里提供了AppComponent里的需要注入的对象。
public class AppModule {
private final MyApp
public AppModule(MyApplication application) {
this.application =
@Singleton
Context provideApplicationContext() {
@Singleton
ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
return jobE
@Singleton
ApiService providesApiService(RetrofitManager retrofitManager) {
return retrofitManager.getService();
@Singleton
SpfManager provideSpfManager() {
return new SpfManager(application);
@Singleton
DBManager provideDBManager() {
return new DBManager(application);
这里细心的童鞋可能发现,为何有些方法直接返回入参,有些需要返回一个new的对象呢?这里如果对DBManager的写法换成:
DBManager provideDBManager(DBManager dbManager) {
return dbM
这样编译不会通过,会报一个循环依赖的错误,这种写法需要在返回参数和入参是继承关系才可以。感兴趣的可以查看dagger2生成的代码。
对于直接返回的类JobExecutor、RetrofitManager,它们类的构造函数一定要加上@Inject的注解:
public JobExecutor() {
接下来谈谈ActivityComponent,可以看到有个@ActivityScope注解,这个注解是自定义的,对应Activity的生命周期,Dagger2可以通过自定义注解限定注解作用域。
@Retention(RUNTIME)
public @interface ActivityScope {}
ActivityComponent:生命周期跟Activity一样的组件,这里提供了inject方法将Activity注入到ActivityComponent中,通过该方法,将Activity中需要注入的对象注入到该Activity中。
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
Activity activity();
void inject(LoginActivity loginActivity);
void inject(MainActivity mainActivity);
ActivityModule:注入Activity,同时规定Activity所对应的域是@ActivityScope
public class ActivityModule {
private final A
public ActivityModule(Activity activity) {
this.activity =
@ActivityScope
Activity activity() {
return this.
至此,注入工作初步完毕了,看到这里,可能有童鞋有疑问,Presenter(或者Biz)的注入在哪里,为何没在ActivityComponent里?是的,正常来说,结构图应该是下面这张图的样子:
我建议使用这种方式,对于不同的Activity,创建各个对应的ActivityCompontent,同时把Presenter(Biz)注入到Component的视图中,这也是dagger2推荐的做法,Dagger 2希望使用@Component注解接口将依赖关系链接起来。
而我的做法没有把Presenter注入到ActivityComponent中,因为Presenter的作用域和Activity一样,好处是节省代码(- -),大家可以根据项目情况自行选择注入方式。
public class LoginActivity extends BaseActivity implements LoginView, ValidCodeView {
@Inject LoginPresenter loginP
@Inject ValidCodePresenter validCodeP
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initInject();
// 此处省略N行代码
private void initInject() {
// 构建Component并注入
getActivityComponent().inject(this);
loginPresenter.attachView(this);
validCodePresenter.attachView(this);
建议写在基类Activity里
protect ActivityComponent getActivityComponent(){
DaggerActivityComponent.builder()
.appComponent(getAppComponent())
.activityModule(getActivityModule())
建议写在基类Activity里
protect ActivityModule getActivityModule(){
return new ActivityModule(this);
// 建议写在MyApplication类里
public AppComponent getAppComponent(){
return DaggerAppComponent.builder()
.appModule(new AppModule((MyApplication)getApplicationContext()))
其中LoginPresenter:
@ActivityScope
public class LoginPresenter extends DefaultMvpPresenter&LoginView, RESTResult&UserVO&& {
// 此处省略
public LoginPresenter(ApiService apiService, ThreadExecutor jobExecutor, SpfManager spfManager) {
this.apiService = apiS
this.jobExecutor = jobE
this.spfManager = spfM
public void login(String mobile, String code) {
这样,dagger2的简单使用就介绍完毕了,如果有对一些基础概念不是很理解的童鞋,可以查看。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
Android深入理解、基础详解及各种Library使用介绍。认真做技术,好好享受人生。。
· 5011人关注
Android开发相关知识和技巧,欢迎大家积极投稿~
· 2896人关注
Android-Rxjava&retrofit
· 154人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

我要回帖

更多关于 团购怎么退款 的文章

 

随机推荐