Dagger2 的使用
一、Dagger2 是什么
Dagger2是第一個(gè)實(shí)現(xiàn)用生成的代碼實(shí)現(xiàn)完整堆棧的庫芦疏。指導(dǎo)原則是生成代碼,該代碼模仿用戶可能手寫的代碼,以確保注入盡可能的簡單涛救,可追蹤和高效。
一业扒、Dagger2 的使用
Dagger 是通過 @Inject
使用具體的某個(gè)對象检吆,這個(gè)對象是有@Provides
注解提供,但是程储,這個(gè)@Provides
只能在固定的模塊中蹭沛,也就是@Module
注解,我們查找的時(shí)候章鲤,不是直接去找模塊摊灭,而是去找@Component
正常我們在類中使用其他類,都是 new 示例對象败徊,如下:
//先定義一個(gè)User
public class User {
private String userName;
private int age;
}
//我們在 Activity 中使用的時(shí)候
public class MainActivity extends AppCompatActivity {
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
user = new User();
}
}
加入后期對象構(gòu)造方法改變帚呼,就會(huì)導(dǎo)致需要同步改相應(yīng)的 new 代碼,這樣就會(huì)增加維護(hù)成本皱蹦,還會(huì)一不小心產(chǎn)生 bug煤杀,Dagger 就是為了解決此類問題而生
開始使用Dagger2
- 引入依賴庫
compile 'com.google.dagger:dagger:2.x'
annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
- 創(chuàng)建 Module
//添加module 注解
@Module
public class MainModule {
}
- 使用Provides實(shí)例化對象
//添加module 注解
@Module
public class MainModule {
//使用provides實(shí)例化對象
@Provides
User provideUser(){
return new User();
}
}
- 創(chuàng)建 Component
@Component(modules = {MainModule.class})
public interface MainComponent {
void inject(MainActivity mainActivity);
}
- Rebuild Project
然后AS會(huì)自動(dòng)生成兩個(gè)文件
6)在 Activity 中使用 User
public class MainActivity extends AppCompatActivity {
@Inject User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第一種關(guān)聯(lián)方式
DaggerMainComponent.builder().build().inject(this);
//第二種關(guān)聯(lián)方式
DaggerMainComponent.create().inject(this);
}
}
三、高級用法
模塊之間的依賴關(guān)系
1)include
@Module (includes = {BModule.class})// 表示Modele包含BModule
2)一個(gè)Component 應(yīng)用多個(gè) module
@Component(modules = {AModule.class,BModule.class})
- dependencies 依賴其他Component
@Component(modules = {MainModule.class}, dependencies = AppConponent.class)
@Named 使用
相當(dāng)于都是同一個(gè)類沪哺,不同Named標(biāo)記的產(chǎn)生的實(shí)例類不同
在Module中定義
@Module
public class MainModule {
//使用provides實(shí)例化對象
@Named("A")
@Provides
User provideUserA(){
return new User();
}
@Named("B")
@Provides
User provideUserB(){
return new User();
}
}
在Activity中定義
public class MainActivity extends AppCompatActivity {
@Named("A")
@Inject User userA;
@Named("B")
@Inject User userB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.create().inject(this);
Log.i("TAG", "userA =="+ userA);
Log.i("TAG", "userB =="+ userB);
}
}
Log打印
09-24 17:09:39.612 14992-14992/? I/TAG: userA ==xl.app.User@f335b59
userB ==xl.app.User@e89331e
@Singleton 單例
簡單示例
//第一沈自,在module中需要單例的對象上添加 @Singleton
@Module
public class MainModule {
@Singleton
@Provides
User provideUser(){
return new User();
}
}
//在Component添加 @Singleton
@Singleton
@Component(modules = {MainModule.class})
public interface MainComponent {
void inject(MainActivity mainActivity);
}
//使用
@Inject User userA;
@Inject User userB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.create().inject(this);
Log.i("TAG", "userA =="+ userA);
Log.i("TAG", "userB =="+ userB);
}
//Log打印
TAG: userA ==xl.app.User@f335b59
userB ==xl.app.User@f335b59
這是我們再建一個(gè)Activity,使用這個(gè)單例
@Singleton
@Component(modules = {MainModule.class})
public interface MainComponent {
void inject(MainActivity mainActivity);
void inject(SubActivity subActivity);
}
public class MainActivity extends AppCompatActivity {
@Inject User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.create().inject(this);
Log.i("TAG", "MainActivity user =="+ user);
}
}
public class SubActivity extends AppCompatActivity {
@Inject
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
DaggerMainComponent.create().inject(this);
Log.i("TAG", "SubActivity user =="+ user);
}
}
//Log 打印
TAG: MainActivity user ==xl.app.User@fcc3200
TAG: SubActivity user ==xl.app.User@43f5bbf
結(jié)果發(fā)現(xiàn)不是同一個(gè)對象了辜妓,這時(shí)候如果想要一個(gè)全局的單例枯途,就需要自定義Scoped
自定義Scoped
/**
* @作者 : allens
* @創(chuàng)建日期 :2017/7/14 下午3:04
* @方法作用:
* 參考Singleton 的寫法
* Scope 標(biāo)注是Scope
* Documented 標(biāo)記在文檔
* @Retention(RUNTIME) 運(yùn)行時(shí)級別
*/
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScoped {
}
Subcomponent
這個(gè)是系統(tǒng)提供的一個(gè)Component,當(dāng)使用Subcomponent,那么默認(rèn)會(huì)依賴Component
@Subcomponent(modules = TestSubModule.class)
public interface TestSubComponent {
void inject(MainActivity activity);
}
=========
@Component(modules = {MainModule.class})
public interface MainConponent {
TestSubComponent add(TestSubModule module);
}
lazy 和 Provider
其中Lazy(懶加載)的作用好比component初始化了一個(gè)present對象,然后放到一個(gè)池子里,需要的時(shí)候就get它,所以你每次get的時(shí)候拿到的對象都是同一個(gè);并且當(dāng)你第一次去get時(shí),它才會(huì)去初始化這個(gè)實(shí)例.
procider(強(qiáng)制加載)的作用:
- 同上當(dāng)你第一次去get時(shí),它才會(huì)去初始化這個(gè)實(shí)例
- 后面當(dāng)你去get這個(gè)實(shí)例時(shí),是否為同一個(gè),取決于他Module里實(shí)現(xiàn)的方式