<![CDATA[C++(一)]]> %2F2018%2F04%2F08%2FCPP-%E4%B8%80%2F C++ <![CDATA[SQLite(三)]]> %2F2018%2F04%2F08%2FSQLite-%E4%B8%89%2F Android SQLite <![CDATA[Source Insight 使用]]> %2F2018%2F04%2F07%2FSource-Insight-%E4%BD%BF%E7%94%A8%2F Tools Source Insight <![CDATA[Java 小知识]]> %2F2018%2F04%2F02%2FJava-%E5%B0%8F%E7%9F%A5%E8%AF%86%2F Java <![CDATA[Window和WindowManager]]> %2F2018%2F04%2F02%2FWindow%E5%92%8CWindowManager%2F Android <![CDATA[SQLite(二)]]> %2F2018%2F04%2F02%2FSQLite-%E4%BA%8C%2F Android SQLite <![CDATA[SQLite(一)]]> %2F2018%2F03%2F30%2FSQLite-%E4%B8%80%2F Android SQLite <![CDATA[Kotlin for Android(七)]]> %2F2018%2F03%2F25%2FKotlin-for-Android-%E4%B8%83%2F Kotlin Android Kotlin <![CDATA[Kotlin for Android(六)]]> %2F2018%2F03%2F24%2FKotlin-for-Android-%E5%85%AD%2F Kotlin Android Kotlin <![CDATA[Kotlin for Android (五)]]> %2F2018%2F03%2F24%2FKotlin-for-Android-%E4%BA%94%2F Kotlin Android Kotlin <![CDATA[Kotlin for Android (四)]]> %2F2018%2F03%2F23%2Fkotlin-for-Android-%E5%9B%9B%2F Kotlin Android Kotlin <![CDATA[Kotlin for Android (三)]]> %2F2018%2F03%2F23%2FKotlin-for-Android-%E4%B8%89%2F 增加内嵌布局,需要手动import 12import kotlinx.android.synthetic.activity_main.*import kotlinx.android.synthetic.content_main.* 绑定一个xml中的view到另一个view。唯一不同的就是需要 import :import kotlinx.android.synthetic.view_item.view.* 在Adapter中可以简化代码 1234567891011121314import kotlinx.android.synthetic.main.item_forecast.view.*class VH(itemView: View, val itemClick: (Forecast) -> Unit) : RecyclerView.ViewHolder(itemView) { fun bindForecast(forecast: Forecast) { with(forecast) { Picasso.with(itemView.context).load(iconUrl).into(itemView.icon) itemView.date.text = date itemView.description.text = description itemView.maxTemperature.text = high.toString() itemView.minTemperature.text = low.toString() itemView.setOnClickListener { itemClick(this) } } } }]]> <![CDATA[Kotlin for Android (二)]]> %2F2018%2F03%2F23%2FKotlin-for-Android-%E4%BA%8C%2F Kotlin Android Kotlin <![CDATA[Kotlin for Android (一)]]> %2F2018%2F03%2F22%2FKotlin-for-Android-%E4%B8%80%2F Kotlin Android Kotlin <![CDATA[RxJava2]]> %2F2018%2F03%2F20%2FRxJava2%2F Android RxJava2 <![CDATA[Data Binding]]> %2F2018%2F03%2F16%2FData-Binding%2F Android <![CDATA[Dagger]]> %2F2018%2F03%2F13%2FDagger%2F 实例。在调用makeApple()方法时,实际上是调用的相应Provider的get()方法,获取相应的实例 123public AppleBean makeApple() { return provideAppleProvider.get();} 依赖对象的注入源应该是有两个,一是Module中的@Provides方法,二是使用@Inject注解的构造函数 单例@Singleton,可以做文档注释,提醒是线程安全 123 @Provides @Singleton static Heater provideHeater() { return new ElectricHeater();} @Qualifier是限定符,而@Named则是基于String的限定符,容易写错,推荐@Qualifier 自定义注解 123456789101112 @Provides @CoolQualifier// @Named("Cool") Water provideCoolWater() { return new CoolWater(); }// 另外的一种方式,这里Water是抽象类,可以考虑其他对象Light灯光// @Provides// Water providePot(@CoolQualifier Water w) {// return new Water(w);// } @Component与@SubComponent Car 12345@Injectpublic Car(Water water) { this.water = water; oil = new Oil();} WaterComponent 123456789101112 /** * @Module标记在类上面 * @Provodes标记在方法上 表示可以通过这个方法获取依赖 */@Component(modules = WaterModule.class)public interface WaterComponent { @HotQualifier Water getHotWater(); @CoolQualifier Water getCoolWater();} CarModule 1234567 @Modulepublic class CarModule { @Provides Car provideCar(@CoolQualifier Water water){ return new Car(water); }} CarComponent 12345678 /** * @Module标记在类上面 * @Provodes标记在方法上 表示可以通过这个方法获取依赖 */@Component(modules = CarModule.class, dependencies = WaterComponent.class)public interface CarComponent { Car getCar();} MainActivityComponent 1234 @Component(dependencies = CarComponent.class)public interface MainActivityComponent { void inject(MainActivity mainActivity);} MainActivity 1234567DaggerMainActivityComponent.builder() .carComponent(DaggerCarComponent.builder() .waterComponent(DaggerWaterComponent.create()) .build()) .build() .inject(this);Log.e(TAG, car.show()); CarComponent依赖WaterComponent,将WaterComponent的引用传递给CarComponent,这样CarComponent就可以使用WaterComponent中的方法。在DaggerCarComponent中的getCar()方法,waterComponent.getCoolWater()获取Water 通过@SubComponent实现 1234567891011121314@Component(modules = WaterModule.class)public interface WaterComponent { CarComponent plus(CarModule carModule);}@Subcomponent(modules = CarModule.class)public interface CarComponent{ MainActivityComponent plus();}@Subcomponentpublic interface MainActivityComponent { void inject(MainActivity mainActivity);} Component和SubComponent区别 1234Component dependencies 能单独使用,而Subcomponent必须由Component调用方法获取。Component dependencies 可以很清楚的得知他依赖哪个Component, 而Subcomponent不确定使用上的区别,Subcomponent就像这样DaggerAppComponent.plus(new SharePreferenceModule());使用Dependence可能是这样DaggerAppComponent.sharePreferenceComponent(SharePreferenceComponent.create()) @Scope和@Singleton@Scope管理依赖的生命周期,@Scope对某类注解后,其作用的核心应该是注入器的控制,注入实例时,控制注入器调用缓存的实例还是重新实例,自定义注解,而@Singleton是@Scope默认实现如果有类注入实例的类被@Scope注解,那么其Component必须被相同的Scope注解 1234@Scope@Documented@Retention(RUNTIME)public @interface Singleton {} 依赖实例的注入来源是@Provides方法时,@Provides方法必须被@Scope注解;如果依赖实例的注入来源是@Inject注解的构造函数时,实例类必须被@Scope注解。这样@Scope注解才会有效。也就是说,@Scope实际上是对注入器的控制 Scope控制的实例的注入器是当前Component之内的实例注入器,而不会影响其他的Component中的实例注入器 更好的管理Component之间的组织方式,用自定义的Scope注解标注这些Component,检查有依赖关系或包含关系的Component,若发现Component没有用自定义Scope注解标注,则会报错 编译器会检查 Component管理的Modules,标注Component的自定义Scope注解与Modules中的标注创建类实例方法的注解不一样会报错 单例实例 1234567891011121314151617181920@InjectCar car1;//可以注入多个Car,但是重新创建了一个依赖@InjectCar car2;//使用单例,@Singleton@Modulepublic class CarModule { @Provides @Singleton Car provideCar(@CoolQualifier Water water){ return new Car(water); }}@Singleton@Component(modules = CarModule.class, dependencies = WaterComponent.class)public interface CarComponent { Car getCar();} 编译报错 12Error:(16, 1) 错误: com.willkernel.www.daggerdemo.component.MainActivityComponent (unscoped) cannot depend on scoped components:@Singleton com.willkernel.www.daggerdemo.component.CarComponent 在Component中指定ModuleMainActivityComponent依赖CarComponent而dagger2规定使用单例的Component,子Component也必须标注@Scope但是不能标注@Singleton,不允许,单例依赖单例不符合设计原则需要自定义一个@Scope,例如ActivityScope@Singleton 需要在@Provide和@Component,还有MainActivityComponent中使用@Scope才能够顺利编译,保持局部单例 可以注入多个Car,但是重新创建了一个依赖,使用单例后两个地址一样, 但是在其他Activity中,地址又不一样,属于局部单例,在其他Activity重新 创建了注入器Component,所以Car对象的地址改变了 Dagger正确使用单例 依赖在Component中是单例的(供该依赖的provide方法和对应的Component类使用同一个Scope注解) 对应的Component在App中只初始化一次,每次注入依赖都使用这个Component对象(在Application中创建该Component) App 123456789101112131415public class App extends Application { private CarComponent carComponent; @Override public void onCreate() { super.onCreate(); carComponent = DaggerCarComponent.builder() .waterComponent(DaggerWaterComponent.create()) .build(); } public CarComponent getCarComponent() { return carComponent; }} SecondActivity 12345678@InjectCar car3;DaggerSecondActivityComponent.builder() .carComponent(((App) getApplication()).getCarComponent()) .build() .inject(this); Log.e(TAG, "car3=" + car3.hashCode()); 也可以通过ApplciationScope使用单例 12345678910111213141516171819202122232425@Scope@Retention(RUNTIME)public @interface ApplicationScope {}public class App extends Application{ @Inject Car car; @Override public void onCreate() { super.onCreate(); DaggerAppComponent.builder().carComponent(DaggerCarComponent.builder() .waterComponent(DaggerWaterComponent.create()).build()) .build() .inject(this); } public Car getCar() { return car; } 在SecondeActivity中引用car6=((App)getApplication()).getCar(); Log.e(TAG, "car6=" + car6.hashCode()); MapKey 1234567891011121314151617181920212223242526272829@Component(modules = MapKeyModule.class)public interface MapComponent { Map<String, String> mapkey();}@Modulepublic class MapKeyModule { @Provides @IntoMap @TestKey("foo") String provideFooKey() { return "foo value"; } @Provides @IntoMap @TestKey("bar") String provideBarKey() { return "bar value"; }}@MapKey(unwrapValue = true)public @interface TestKey { String value();}Map<String, String> map = DaggerMapComponent.create().mapkey(); Log.e(TAG, "map " + map.toString()); Lazy通过Lazy提供的实例,在@Inject的时候并不初始化,而是使用的时候,主动调用其get方法来获取实例,并且会缓存该对象 12345@InjectLazy<Car> carLazy;Car carL = carLazy.get();Log.e(TAG, "carL " + carL.show()); Provider有时您需要注入多个实例列表,而不是注入单个值。可以注入一个Provider ,而不只是T。当Provider 每次调用get()方法时,都会执行绑定逻辑并创建一个新的实例,地址不一样,但@Scope注解的类地址是一样的 1234567891011121314@CoffeeScopepublic class CoffeeBean { @Inject public CoffeeBean() { Log.d("test", "Coffee()"); }} @Inject Provider<CoffeeBean> mCoffeeBeanProvider CoffeeBean beanA = mCoffeeBeanProvider.get(); CoffeeBean beanB = mCoffeeBeanProvider.get(); 多个元素绑定并注入到Set 将单个元素注入到Set 1234567@Moduleclass MyModuleA { @Provides @IntoSet static String provideOneString(DepA depA, DepB depB) { return "ABC"; }} Set 注入到Set 1234567 @Moduleclass MyModuleB { @Provides @ElementsIntoSet static Set<String> provideSomeStrings(DepA depA, DepB depB) { return new HashSet<String>(Arrays.asList("DEF", "GHI")); }} 在Component中,表明注入到Set的实例的提供Module,声明setApple()方法,用来提供集合Set 1234567891011121314151617 class Bar { @Inject Bar(Set<String> strings) { assert strings.contains("ABC"); assert strings.contains("DEF"); assert strings.contains("GHI"); }} 或者 @Component(modules = {MyModuleA.class, MyModuleB.class})interface MyComponent { Set<String> strings();}@Test void testMyComponent() { MyComponent myComponent = DaggerMyComponent.create(); assertThat(myComponent.strings()).containsExactly("ABC", "DEF", "GHI");} 也可以通过Provider<Set> or Lazy<Set>来依赖注入实例,但是不能通过Set<Provider>> 增加限定符@Qualifier 1234567891011121314@Moduleclass MyModuleC { @Provides @IntoSet @MyQualifier static Foo provideOneFoo(DepA depA, DepB depB) { return new Foo(depA, depB); }}@Moduleclass MyModuleD { @Provides static FooSetUser provideFooSetUser(@MyQualifier Set<Foo> foos) { ... }} 多个元素绑定并注入到Map在Module中的@Provides方法使用@IntoMap,同时指定该元素的Key(例如@StringKey(“foo”),@ClassKey(Thing.class),@IntKey(12),@LongKey(100L)),没有这个key时,返回null 123456789101112131415161718192021222324252627 @Moduleclass MyModule { @Provides @IntoMap @StringKey("foo") static Long provideFooValue() { return 100L; } @Provides @IntoMap @ClassKey(Thing.class) static String provideThingValue() { return "value for Thing"; }}@Component(modules = MyModule.class)interface MyComponent { Map<String, Long> longsByString(); Map<Class<?>, String> stringsByClass();}@Test void testMyComponent() { MyComponent myComponent = DaggerMyComponent.create(); assertThat(myComponent.longsByString().get("foo")).isEqualTo(100L); assertThat(myComponent.stringsByClass().get(Thing.class)) .isEqualTo("value for Thing");} 如果key是枚举或其他特定的类,使用@MapKey注解,自定义Key 自定义枚举类型,数据包装类key如果不满足指定的返回类型,那么编译时会报错:基本数据类型StringClass(参数化类,? extends Number)枚举类型注解类型以上数据类型的数组 12345678910111213enum MyEnum { ABC, DEF;} @MapKey@interface MyEnumKey { MyEnum value();}@MapKey@interface MyNumberClassKey { Class<? extends Number> value();} 在Module中的@Prvoides使用@IntoMap,并指明key 1234567891011121314 @Moduleclass MyModule { @Provides @IntoMap @MyEnumKey(MyEnum.ABC) static String provideABCValue() { return "value for ABC"; } @Provides @IntoMap @MyNumberClassKey(BigDecimal.class) static String provideBigDecimalValue() { return "value for BigDecimal"; }} 注入器Component 123456789101112 @Component(modules = MyModule.class)interface MyComponent { Map<MyEnum, String> myEnumStringMap(); Map<Class<? extends Number>, String> stringsByNumberClass();}@Test void testMyComponent() { MyComponent myComponent = DaggerMyComponent.create(); assertThat(myComponent.myEnumStringMap().get(MyEnum.ABC)).isEqualTo("value for ABC"); assertThat(myComponent.stringsByNumberClass.get(BigDecimal.class)) .isEqualTo("value for BigDecimal");} 组合的MapKey,设置unwrapValue的值为false,这样key值也可以是数组成员,key不唯一指定,可以有多个不同类型的key 1234567891011121314151617181920 @MapKey(unwrapValue = false)@interface MyKey { String name(); Class<?> implementingClass(); int[] thresholds();}@Moduleclass MyModule { @Provides @IntoMap @MyKey(name = "abc", implementingClass = Abc.class, thresholds = {1, 5, 10}) static String provideAbc1510Value() { return "foo"; }}@Component(modules = MyModule.class)interface MyComponent { Map<MyKey, String> myKeyStringMap();} 使用MapKey,需要生成Mykey的静态方法,就需要使用@AutoAnnotation 123456789101112131415 apt 被annotationProcessor替代 apply plugin: 'com.neenbedankt.android-apt' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' annotationProcessor "com.google.auto.value:auto-value-annotations:1.5" implementation "com.google.auto.value:auto-value:1.5" @AutoAnnotationstatic MyKey createMyKey(String name, Class<?> implementingClass, int[] thresholds) { return new AutoAnnotation_MainActivity_createMyKey(name, implementingClass, thresholds); } MyKeyComponent myKeyComponent = DaggerMyKeyComponent.create(); Log.e(TAG, "myKeyComponent "+myKeyComponent.myKeyStringMap() .get(createMyKey("abc", BigDecimal.class, new int[]{1, 2, 4}))); Mapkey的key在编译期间未知,就不能创建Mapkey的绑定,不过可以先设置绑定Set,再转换为Map绑定 12345678910111213141516171819202122232425262728 @Moduleclass MyModule { @Provides @IntoSet static Map.Entry<Foo, Bar> entryOne(...) { Foo key = ...; Bar value = ...; return new SimpleImmutableEntry(key, value); } @Provides @IntoSet static Map.Entry<Foo, Bar> entryTwo(...) { Foo key = ...; Bar value = ...; return new SimpleImmutableEntry(key, value); }}@Moduleclass MyMapModule { @Provides static Map<Foo, Bar> fooBarMap(Set<Map.Entry<Foo, Bar>> entries) { Map<Foo, Bar> fooBarMap = new LinkedHashMap<>(entries.size()); for (Map.Entry<Foo, Bar> entry : entries) { fooBarMap.put(entry.getKey(), entry.getValue()); } return fooBarMap; }} Dagger并不会自动注入Map\<Foo,Provider\<Bar>>,也就意味着不会提供一个含有Provider值得Map。如果想要获取一个含有Provider的Map,需要在Map.Entry对象中包含Provider值,那么所获取的Map也就含有Provider 123456789101112131415161718@Moduleclass MyModule { @Provides @IntoSet static Map.Entry<Foo, Provider<Bar>> entry( Provider<BarSubclass> barSubclassProvider) { Foo key = ...; return new SimpleImmutableEntry(key, barSubclassProvider); }}@Moduleclass MyProviderMapModule { @Provides static Map<Foo, Provider<Bar>> fooBarProviderMap( Set<Map.Entry<Foo, Provider<Bar>>> entries) { return ...; }} 声明多重绑定@Multibinds-annotated,也可以使用@IntoSet,@IntoMap,@ElementsIntoSet,但是必须有一个 1234567@Moduleabstract class MyModule { @Multibinds abstract Set<Foo> aSet(); @Multibinds @MyQualifier abstract Set<Foo> aQualifiedSet(); @Multibinds abstract Map<String, Foo> aMap(); @Multibinds @MyQualifier abstract Map<String, Foo> aQualifiedMap();} Set或Map多重绑定可以声明任意次数而不会发生错误。Dagger从不实现或调用任何@Multibinds方法添加返回空集合的@ElementsIntoSet方法 1234567@Moduleclass MyEmptySetModule { @Provides @ElementsIntoSet static Set<Foo> primeEmptyFooSet() { return Collections.emptySet(); }} 添加子组件方式 @Component的dependencies属性依赖父组件 1234 @Component(modules = OrangeModule.class, dependencies = FruitComponent.class)public interface OrangeComponent { ***} @Module的Subcomponents添加子组件 12345 @Module(subcomponents = AppleSubcomponent.class)public class FruitModule { ***} @SubComponent声明子组件,需要提供@Subcomponent.Builder接口的Builder,build()来构建子组件 12345678910@Subcomponent(modules = RequestModule.class)interface RequestComponent { RequestHandler requestHandler(); @Subcomponent.Builder interface Builder { Builder requestModule(RequestModule module); RequestComponent build(); }} 添加子组件到父组件,添加子组件类到父组件的@Module的subcomponents属性,然后父组件调用子组件的builder方法 12@Module(subcomponents = RequestComponent.class)class ServerModule {} 父组件的注入器 123456789101112131415161718192021@Singleton@Component(modules = ServerModule.class)interface ServerComponent { RequestRouter requestRouter();}子组件实例注入@Singletonclass RequestRouter { @Inject RequestRouter( Provider<RequestComponent.Builder> requestComponentProvider) {} void dataReceived(Data data) { RequestComponent requestComponent = requestComponentProvider.get() .data(data) .build(); requestComponent.requestHandler() .writeResponse(200, "hello, world"); }} 子组件和作用域,如果没有作用域的绑定,每次注入都会重新创建独立的对象,但是如果有作用域绑定的对象,在作用域生命周期中绑定的对象实例是同一个 子组件和父组件的作用域不能相同,比父组件的生命周期短,两个子组件有不同的作用域实例,即使他们的作用域注解相同 12345678910111213141516@Singleton @Componentinterface RootComponent { SessionComponent.Builder sessionComponent();}@SessionScope @Subcomponentinterface SessionComponent { FooRequestComponent.Builder fooRequestComponent(); BarRequestComponent.Builder barRequestComponent();}@RequestScope @Subcomponentinterface FooRequestComponent {...}@RequestScope @Subcomponentinterface BarRequestComponent {...} 封装子组件在不同Service,不同界面,共享某些绑定,但是这些绑定中也有不需要的绑定实例,这时就需要使用子组件,对绑定实例进行细分 应用ApplicationComponent,注入数据库实例 12345 @Singleton @Component(modules = DatabaseModule.class)interface ApplicationComponent { Database database();} 数据库模块,子组件为DatabaseComponent 12345678910111213 @Module(subcomponents = DatabaseComponent.class)class DatabaseModule { @Provides @Singleton Database provideDatabase( @NumberOfCores int numberOfCores, DatabaseComponent.Builder databaseComponentBuilder) { return databaseComponentBuilder .databaseImplModule(new DatabaseImplModule(numberOfCores / 2)) .build() .database(); }} 数据库实现类模块 123456 @Moduleclass DatabaseImplModule { DatabaseImplModule(int concurrencyLevel) {} @Provides DatabaseConnectionPool provideDatabaseConnectionPool() {} @Provides DatabaseSchema provideDatabaseSchema() {}} 子组件 1234 @Subcomponent(modules = DatabaseImplModule.class)interface DatabaseComponent { @PrivateToDatabase Database database();} 抽象工厂方法定义子组件 扩展多重绑定 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263@Subcomponent(modules = DatabaseImplModule.class)interface DatabaseComponent { @PrivateToDatabase Database database();}@Moduleclass ParentModule { @Provides @IntoMap @StringKey("one") static int one() { return 1; } @Provides @IntoMap @StringKey("two") static int two() { return 2; } @Provides @IntoSet static String a() { return "a" } @Provides @IntoSet static String b() { return "b" }}@Subcomponent(modules = ChildModule.class)interface Child { Map<String, Integer> map(); Set<String> set();}@Moduleclass ChildModule { @Provides @IntoMap @StringKey("three") static int three() { return 3; } @Provides @IntoMap @StringKey("four") static int four() { return 4; } @Provides @IntoSet static String c() { return "c" } @Provides @IntoSet static String d() { return "d" }}Parent parent = DaggerParent.create();Child child = parent.child();assertThat(parent.map().keySet()).containsExactly("one", "two");assertThat(child.map().keySet()).containsExactly("one", "two", "three", "four");assertThat(parent.set()).containsExactly("a", "b");assertThat(child.set()).containsExactly("a", "b", "c", "d"); 模块Module作为工厂方法的参数会在编译时报错,重复模块Module在依赖注入获取对象时引用是运行时错误 123456789101112131415161718192021@Component(modules = {RepeatedModule.class, ...})interface ComponentOne { ComponentTwo componentTwo(RepeatedModule repeatedModule); // COMPILE ERROR! ComponentThree.Builder componentThreeBuilder();}@Subcomponent(modules = {RepeatedModule.class, ...})interface ComponentTwo { ... }@Subcomponent(modules = {RepeatedModule.class, ...})interface ComponentThree { @Subcomponent.Builder interface Builder { Builder repeatedModule(RepeatedModule repeatedModule); ComponentThree build(); }}DaggerComponentOne.create().componentThreeBuilder() .repeatedModule(new RepeatedModule()) // UnsupportedOperationException! .build(); Dagger Android 引入Dagger 1234567// Dagger dependenciesannotationProcessor "com.google.dagger:dagger-compiler:$rootProject.daggerVersion"provided 'org.glassfish:javax.annotation:10.0-b28'compile "com.google.dagger:dagger:$rootProject.daggerVersion"compile "com.google.dagger:dagger-android:$rootProject.daggerVersion"compile "com.google.dagger:dagger-android-support:$rootProject.daggerVersion"annotationProcessor "com.google.dagger:dagger-android-processor:$rootProject.daggerVersion" @Binds注解委托绑定模块的抽象方法,例如绑定Random到SecureRandom模块 1@Binds abstract Random bindRandom(SecureRandom secureRandom); 是@Provides的替代方法,更高效 @Binds method必须是抽象方法必须是一个可以转换为返回值类型的参数,参数是返回值类型的子类或实现类,将返回值类绑定到参数类,将参数暴露为返回值类型,不需要实例化参数对象可以有限定符@Qualified和作用域@Scoped1234@Documented@Retention(RUNTIME)@Target(METHOD)public @interface Binds {} @ContributesAndroidInjector注解的方法生成的返回值对应的AndroidInjector。该注入器是 dagger.Subcomponent的实现,而且是dagger.Module 的子Component用于注解返回具体的Android框架类型(例如:FooActivity、BarFragment、MyService等)的dagger.Module中的无参抽象方法 BindsInstance 标识组件或子组件的Builder方法,绑定对象到组件中的类 12345@Documented@Retention(RUNTIME)@Target(METHOD)@Betapublic @interface BindsInstance {} 注入实例由于DispatchingAndroidInjector在运行时由类查找相应的AndroidInjector.Factory,那么,在基类中,实现HasActivityInjector/HasFragmentInjector接口,在相应的声明周期(onCreate()或者onAttach())内调用AndroidInjection.inject()方法,注入相应的实例。所有每个子类都需要做的是绑定相应的@Subcomponent,从而没有必要在每个实例类中调用AndroidInjection.inject()方法。 12345678910111213141516@Betapublic abstract class DaggerActivity extends Activity implements HasFragmentInjector { @Inject DispatchingAndroidInjector<Fragment> fragmentInjector; @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); } @Override public AndroidInjector<Fragment> fragmentInjector() { return fragmentInjector; }} 在dagger.android库中,有一些基本类型,对于Appliaction是DaggerApplication,只需重写applicationInjectoer()方法来返回AndroidInjector\<XxApplication>Dagger提供的基本类型:DaggerActivityDaggerFragmentDaggerServiceDaggerIntentServiceDaggerBroadcastReceiverDaggerContentProvider 参考 github-dagger-demo Dagger 2从浅到深 Dagger2 Dagger2 最清晰的使用教程]]> Android <![CDATA[ConstraintLayout]]> %2F2018%2F03%2F10%2FConstraintLayout%2F Android <![CDATA[CoordinatorLayout]]> %2F2018%2F03%2F09%2FCoordinatorLayout%2F Android <![CDATA[Git]]> %2F2018%2F03%2F09%2FGit%2F Git Git <![CDATA[NDK]]> %2F2018%2F03%2F09%2FNDK%2F Android NDK <![CDATA[MVP(loader/dagger/rxjava2)]]> %2F2018%2F03%2F09%2FMVP%2F <![CDATA[Kotlin 入门]]> %2F2018%2F03%2F09%2FKotlin%E5%85%A5%E9%97%A8%2F Kotlin Android Kotlin <![CDATA[MVVM]]> %2F2018%2F03%2F09%2FMVVM%2F Android <![CDATA[Android Notes(Performance)]]> %2F2018%2F03%2F08%2FAndroid-Notes-Performance%2F Android <![CDATA[Android Notes(System Info Manager Safety)]]> %2F2018%2F03%2F08%2FAndroid-Notes-System-Info-Manager-Safety%2F Android <![CDATA[Android Notes(Activity)]]> %2F2018%2F03%2F07%2FAndroid-Notes-Activity%2F Android <![CDATA[Android Notes(SurfaceView)]]> %2F2018%2F03%2F07%2FAndroid-Notes-SurfaceView%2F Android <![CDATA[Android Notes(Paint Shader)]]> %2F2018%2F03%2F07%2FAndroid-Notes-Paint-Shader%2F Android <![CDATA[Android Notes(View)]]> %2F2018%2F03%2F05%2FAndroid-Notes-View%2F Android <![CDATA[Android Notes (ListView Scroller)]]> %2F2018%2F03%2F02%2FAndroid-Notes-ListView-Scroller%2F Android <![CDATA[Docker 编译Android源码]]> %2F2018%2F02%2F26%2FDocker-%E7%BC%96%E8%AF%91Android%E6%BA%90%E7%A0%81%2F Android Docker 源码 <![CDATA[Android Notes (System ADB UI)]]> %2F2018%2F02%2F25%2FAndroid-Notes%2F Android <![CDATA[sh 简单程序]]> %2F2018%2F02%2F24%2Fsh-%E7%AE%80%E5%8D%95%E7%A8%8B%E5%BA%8F%2F Linux <![CDATA[Linux 常用快捷键 命令 设置等操作]]> %2F2018%2F02%2F24%2FLinux-%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE%2F Linux Skills