本文为《Android Architecture Components学习笔记》的一部分
文档代码为Kotlin,但是系统生成的代码仍然为Java
为了方便理解,我将官方示例做了逐步拆解
本人水平有限,如有不当之处请不吝赐教
上一篇分析了Dagger的基本使用方法,还是很弱爆的。在项目里如何应用呢,本篇捋一下Activity对象注入的那些事。
说明一下GithubApp
这个类,在AndroidManifest
里:
android:name
属性是用来设置所有activity属于哪个application的
GithubApp
这个类放的是全局成员,代码中的AppInjector.init(this)
在activity之前执行
AppInjector.init(this)
也是所有注入的开始。
第一步,跟上篇一样先看注入者GithubApp
:
//需要实现HasActivityInjector
class GithubApp : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
……
//重写了onCreate(),此句是重点
AppInjector.init(this)
}
override fun activityInjector() = dispatchingAndroidInjector
}
第二步,Component:
@Component(modules = [AndroidInjectionModule::class])
interface AppComponent {
//此处声明了Builder
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
fun inject(githubApp: GithubApp)
}
build后
GithubApp_MembersInjector
、DaggerAppComponent
就出来了
GithubApp 是Application,所以这里实现了HasActivityInjector
,从而能够实现Activity的注入
这里还有一个很重要的类:DispatchingAndroidInjector
。后面会详细说
object AppInjector {
fun init(githubApp: GithubApp) {
//第一句:完成对githubApp的注入
DaggerAppComponent.builder().application(githubApp).build().inject(githubApp)
//第二句:override onActivityCreated,加入handleActivity
githubApp.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {handleActivity(activity)}
})
}
private fun handleActivity(activity: Activity) {...}//为了好看,这里先收起来
}
先看AppInjector.init
第一句:
DaggerAppComponent.builder()//通过此静态方法得到Builder
.application(githubApp)//包含githubApp的Builder
.build()//得到DaggerAppComponent对象
.inject(githubApp)
这里用到的DaggerAppComponent
几个方法:
public final class DaggerAppComponent implements AppComponent {
private DaggerAppComponent(Builder builder) {}
public static AppComponent.Builder builder() { return new Builder();}
private DispatchingAndroidInjector<Activity> getDispatchingAndroidInjectorOfActivity() {
//此处返回了一个空Map的DispatchingAndroidInjector
return DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector(
Collections.<~> emptyMap());
}
//将DispatchingAndroidInjector注入到githubApp.dispatchingAndroidInjector
@Override
public void inject(GithubApp githubApp) {injectGithubApp(githubApp);}
private GithubApp injectGithubApp(GithubApp instance) {
GithubApp_MembersInjector.injectDispatchingAndroidInjector(instance, getDispatchingAndroidInjectorOfActivity());
return instance;
}
//此处实现的 AppComponent.Builder,就是前面写在Component里的
//重写的application、build是我们自己定义的
private static final class Builder implements AppComponent.Builder {
private Application application;
@Override
public AppComponent build() {return new DaggerAppComponent(this);}
@Override
public Builder application(Application application) {
this.application = Preconditions.checkNotNull(application);
return this;
}
}
}
代码雪薇有点复杂,这里只需要记住两点:
1、AppInjector.init
第一句完成了githubApp.dispatchingAndroidInjector注入
2、通过GithubApp_MembersInjector
实现。(代码不难,上篇都叨叨过)
这里出现了DispatchingAndroidInjector
在继续AppInjector.init
第二句前,先看看它吧
先看DispatchingAndroidInjector
/*
* 对核心Android类型的实例(Activity、Fragment……)执行注入,它是由Android框架而不是Dagger实现的
* 实现了AndroidInjector,具体类可通过AndroidInjector.Factory注入依赖类
* 通过在实例上调用Object#getClass(),就可以得到它的AndroidInjector.Factory
*/
@Beta
public final class DispatchingAndroidInjector<T> implements AndroidInjector<T> {
/*注入Factory的Map类型,下面代码为了方便看Map类型都省略了
*这个Map中K就是Class,V是AndroidInjector.Factory
*/
private final Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>> injectorFactories;
@Inject
DispatchingAndroidInjector(Map<~> injectorFactories) {
this.injectorFactories = injectorFactories;
}
//尝试在 {instance}上注入, 返回是否成功
@CanIgnoreReturnValue
//能否在Map中获取factory
public boolean maybeInject(T instance) {
Provider<AndroidInjector.Factory<? extends T>> factoryProvider =
injectorFactories.get(instance.getClass());
if (factoryProvider == null) {return false;}
@SuppressWarnings("unchecked")
AndroidInjector.Factory<T> factory = (AndroidInjector.Factory<T>) factoryProvider.get();
//转型后执行注入
try {
AndroidInjector<T> injector =checkNotNull(factory.create(instance),, );
injector.inject(instance);
return true;
} catch (ClassCastException e) {…}
}
//对{instance}执行成员注入
@Override
public void inject(T instance) {
boolean wasInjected = maybeInject(instance);
}
}
通过看DispatchingAndroidInjector
核心代码,它主要通过:
AndroidInjector.create()
、AndroidInjector.inject()
完成注入。
到这里了会有些凌乱,记住DispatchingAndroidInjector以及AppInjector到后面就会清晰了
我们来完成MainActivity
加入DispatchingAndroidInjector
(我是将示例代码逐步完成的)
这时的MainActivity
是这个样子:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
}
}
还是一般规律,Module:
@Suppress("unused")
@Module
abstract class MainActivityModule {
@ContributesAndroidInjector
abstract fun contributeMainActivity(): MainActivity
}
OK,build一下看DaggerAppComponent
public final class DaggerAppComponent implements AppComponent {
//MainActivity的Provider
private Provider<MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder>
mainActivitySubcomponentBuilderProvider;
//构造函数,执行初始化
private DaggerAppComponent(Builder builder) {initialize(builder);}
private void initialize(final Builder builder) {
//初始化MainActivity的Provider
this.mainActivitySubcomponentBuilderProvider =
new Provider<MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder>() {
@Override
public MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder get() {
return new MainActivitySubcomponentBuilder();
}
};
}
public static AppComponent.Builder builder() {return new Builder();}
//得到包含MainActivity的Map
private Map<~> getMapOfClassOfAndProviderOfFactoryOf() {
return Collections.<~>
singletonMap(MainActivity.class, (Provider) mainActivitySubcomponentBuilderProvider);
}
//创建并返回含MainActivity的Map的DispatchingAndroidInjector对象
private DispatchingAndroidInjector<Activity> getDispatchingAndroidInjectorOfActivity() {
return DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector(
getMapOfClassOfAndProviderOfFactoryOf());
}
//执行注入
@Override
public void inject(GithubApp githubApp) {injectGithubApp(githubApp);}
private GithubApp injectGithubApp(GithubApp instance) {
GithubApp_MembersInjector.injectDispatchingAndroidInjector(
instance, getDispatchingAndroidInjectorOfActivity());
return instance;
}
//此处代码略,前面分析过
private static final class Builder implements AppComponent.Builder {...}
private final class MainActivitySubcomponentBuilder
extends MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder {
private MainActivity seedInstance;
@Override//此处重写的是AndroidInjector.Builder.build()
public MainActivityModule_ContributeMainActivity.MainActivitySubcomponent build() {
if (seedInstance == null) {
throw new IllegalStateException(MainActivity.class.getCanonicalName() + " must be set");
}
return new MainActivitySubcomponentImpl(this);
}
@Override//此处重写的是AndroidInjector.Builder.seedInstance()
public void seedInstance(MainActivity arg0) {
this.seedInstance = Preconditions.checkNotNull(arg0);
}
}
private final class MainActivitySubcomponentImpl
implements MainActivityModule_ContributeMainActivity.MainActivitySubcomponent {
private MainActivitySubcomponentImpl(MainActivitySubcomponentBuilder builder) {}
@Override//此处是AndroidInjector.inject()
public void inject(MainActivity arg0) {}
}
}
代码较多,简单来说就是通过DispatchingAndroidInjector
完成了MainActivity的注入。
得先有个Activity,就叫Activity2吧
在Module里添加:
@Suppress("unused")
@Module
abstract class MainActivityModule {
@ContributesAndroidInjector
abstract fun contributeMainActivity(): MainActivity
@ContributesAndroidInjector
abstract fun contributeActivity2(): Activity2
}
build后,再看DaggerAppComponent
public final class DaggerAppComponent implements AppComponent {
private Provider<MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder>
mainActivitySubcomponentBuilderProvider;
//多了Activity2
private Provider<MainActivityModule_ContributeActivity2.Activity2Subcomponent.Builder>
activity2SubcomponentBuilderProvider;
//成了这样子,Map里加入了两个
private Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>
getMapOfClassOfAndProviderOfFactoryOf() {
return MapBuilder
.<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>
newMapBuilder(2)
.put(MainActivity.class, (Provider) mainActivitySubcomponentBuilderProvider)
.put(Activity2.class, (Provider) activity2SubcomponentBuilderProvider)
.build();
}
//这里也是两套
private void initialize(final Builder builder) {
this.mainActivitySubcomponentBuilderProvider =...
this.activity2SubcomponentBuilderProvider =...
}
private final class MainActivitySubcomponentBuilder
extends MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.Builder {...}
private final class MainActivitySubcomponentImpl
implements MainActivityModule_ContributeMainActivity.MainActivitySubcomponent {...}
private final class Activity2SubcomponentBuilder
extends MainActivityModule_ContributeActivity2.Activity2Subcomponent.Builder {...}
private final class Activity2SubcomponentImpl
implements MainActivityModule_ContributeActivity2.Activity2Subcomponent {...}
}
都double了……