android技术

dagger.android的简单使用

2018-11-09  本文已影响0人  Active_Loser

dagger.android

一、简介

dagger.androidDagger的一个扩展,简单的说就是我们虽然降低了程序的耦合性,但是我们改变一个模块是,其中所对应的View中的代码仍然要改变,也就是说我们仍然要在Activity等中添加injet()等代码,因此为了解决这个问题,就引入了dagger.android,官方学习地址Github,本文就其基本使用与优化实战进行整理。

Dagger提供的基本类型:

二、基本使用

添加依赖

compile 'com.google.dagger:dagger-android:2.19'
compile 'com.google.dagger:dagger-android-support:2.19'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.19'

1、注入Activity

(1)创建MainComponent继承AndroidInjector,其抽象类Builder@Subcomponent.Builder注解。

@Subcomponent(modules = {AndroidInjectionModule.class})
public interface MainComponent extends AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }
}

(2)创建Student

public class Student {
    private static final String TAG = "Student";
    public void say(String name) {
        Log.i(TAG, "say: 我是学生,我叫" + name);
    }
}

(3) 创建MainModule,定义子组件MainComponent后,定义该子组件的MainModule,通过将该Module注入AppComponentdmodules列表中,以便将MainActivitySubcomponent.Builder添加到组件层次机构中。

@Module(subcomponents = MainComponent.class)
public abstract class MainModule {

    @Binds
    @ActivityKey(MainActivity.class)
    @IntoMap
    abstract AndroidInjector.Factory<? extends Activity>
        bindYourActivityInjectorFactory(MainComponent.Builder  builder);

    //注意:必须添加@Singleton,否则报错
    @Singleton
    @Provides
    static Student provideStudent(){
        return new Student();
    }
}

(4)为了使得我们的注解可以注入到ActivityFragmentServiceBroadcastReceiver等中,我们通常把AndroidInjectionModule放在ApplicationCoponent中。

@Component(modules = AndroidInjectionModule.class)
    public interface APPComponent {
        void inject(App app);
}

(5)自定义Application实现HasActivityInjector并且通过@Inject注入一个activityInjector()方法返回的DispathcingAndroidInJector<Activity>实例

 public class App extends Application  implements HasActivityInjector {
    @Inject
    DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerTodoComponent.create().inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingActivityInjector;
    }
}

(6)在调用super.onCreate()之前调用AndroidInjection.inject(this)


public class MainActivity extends AppCompatActivity {

    @Inject
    Student mStudent;
    private static final String TAG = "MainActivity";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStudent.say("小明");
    }
}

输出:11-06 22:05:59.884 1149-1149/? I/Student: say: 我是学生,我叫小明

简单分析:AndroidInjection.inject()从应用Application中拿到一个DispatchingAndroidInjector<Activity>并通过inject(Activity)Activity传过去。这个DispatchingAndroidInjector会查找Activity类的AndroidInjector.Factory(YourActivitySubcomponent.Builder),构建AndroidInjector(YourActivitySubcomponent),然后把Activity传给inject(YourActivity),这样就自动完成了注入。

2、注入Fragment

注入FragmentActivity使用基本相同,下面列出不同:

这里列出官网的一些代码:

public class YourActivity extends Activity implements HasFragmentInjector {
  @Inject
  DispatchingAndroidInjector<Fragment> fragmentInjector;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    super.onCreate(savedInstanceState);
  }

  @Override
  public AndroidInjector<Fragment> fragmentInjector() {
    return fragmentInjector;
  }
}
public class YourFragment extends Fragment {
  @Inject
  SomeDependency someDep;

  @Override
  public void onAttach(Activity activity) {
    AndroidInjection.inject(this);
    super.onAttach(activity);
  }
}
@Subcomponent(modules = ...)
public interface YourFragmentSubcomponent extends AndroidInjector<YourFragment> {
  @Subcomponent.Builder
  public abstract class Builder extends AndroidInjector.Builder<YourFragment> {}
}
@Module(subcomponents = YourFragmentSubcomponent.class)
abstract class YourFragmentModule {
  @Binds
  @IntoMap
  @FragmentKey(YourFragment.class)
  abstract AndroidInjector.Factory<? extends Fragment>
      bindYourFragmentInjectorFactory(YourFragmentSubcomponent.Builder builder);
}
@Subcomponent(modules = { YourFragmentModule.class, ... }
public interface YourActivityOrYourApplicationComponent { ... }

三、优化

通过上面的学习,我们可以看出dagger.android的使用,并没有使dagger使用更加方便,因此我们需要对其使用进行优化,这就用到@ContributesAndroidInjector了。

@ContributesAndroidInjector可以返回对应activity,因此使用@ContributesAndroidInjector对其进行注解,并指定要安装到子组件中的模块。

@ActivityScope
@ContributesAndroidInjector(modules = { /* modules to install into the subcomponent */ })
abstract YourActivity contributeYourActivityInjector();

使用方法:

(1)创建Student

public class Student {

    private static final String TAG = "Student";
    
    public void say(String name) {
        Log.i(TAG, "say: 我是学生,我叫" + name);
    }
}

(2)创建MainActivityModule,用以给MainActivity提供各种对象,如:Student

@Module
public class MainActivityModule {

    @Provides
    Student provideStudent(){
        return new Student();
    }
}

(3)创建BaseActivity,用以返回所有的对应activity

@Module
public abstract class BaseActivityModule {

    @ContributesAndroidInjector(modules = {MainActivityModule.class})
    abstract MainActivity bindMainActivity();
}

(4)为了使得我们的注解可以注入到ActivityFragmentServiceBroadcastReceiver等中,我们通常把AndroidInjectionModule放在ApplicationCoponent中。

@Component(modules = {AndroidInjectionModule.class,
        AndroidSupportInjectionModule.class,
        BaseActivityModule.class})
public interface AppComponent extends AndroidInjector<App> {
    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder app(App app);

        AppComponent build();
    }

    void inject(App app);
}

(5)自定义Application继承DaggerApplication,使得ApplicationAppComponent绑定。

public class App extends DaggerApplication {
    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        AppComponent appComponent = DaggerAppComponent.builder().app(this).build();
        return appComponent;
    }
}

(6)输出Student

public class MainActivity extends DaggerAppCompatActivity {

    @Inject
    Student mStudent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStudent.say("小明");
    }
}

输出:11-09 22:01:48.365 1152-1152/? I/Student: say: 我是学生,我叫小明

上一篇 下一篇

猜你喜欢

热点阅读