Dagger2-android (不是dagger2)使用

Dagger2

最近在android中使用dagger2做开发的项目越来越多了,然后去学习了下dagger2,在github上面看了不少关于dagger2的demo,但是感觉dagger2在android中并不是太好使用了,例如本人看过的一些列子

将对象注入到Activity中

写法一

public interface AppComponent{
    void inject(SplashActivity activity);
    void inject(MainActivity activity);
    void inject(GuideFragment fragment);
    ...
}

这种写法是在Application中生成AppComponent对象 然后提供全局获取这个对象的static方法 在其他Activity中调用inject(xxxxxx)

写法二

对于Activity

public interface ActivityComponent{
    void inject(SplashActivity activity);
    void inject(MainActivity activity);
    ...
}

这里写代码片

对于Fragment

public interface FragmentComponent{
    void inject(GuideFragment fragment);
    ...
}

然后每个activity和fragment创建的时候去创建对应的ActivityComponent与FragmentComponent对象

说明

对于方法一来说 AppCompoent中inject方法可能或很多
方法二 每个Activity与Fragment中都需要 DaggerXXXX.create().inject(xxxx)

这个没有统一的写法,所以我再github上面看别人的demo很头疼,所以项目一直没准备上dagger2,前段时间无聊,去google的github看了下dagger2的最新版本,在里面发现了一个新东西dagger2-android,然后百度了下dagger2-android ,结果没看到一篇文章介绍这个…..感觉有点悲剧,然后自己就看dagger2官方指导,学习了下这个框架,个人感觉相对于dagger2在android中的使用,dagger2-android更加适合

感觉有点不好说,先上代码吧
gradle 配置如下

dependencies {
    compile 'com.google.dagger:dagger:2.11'
    compile 'com.google.dagger:dagger-android:2.11-rc2'
    compile 'com.google.dagger:dagger-android-support:2.11-rc2'
    compile 'com.google.errorprone:error_prone_annotations:2.0.19'

    annotationProcessor 'com.google.dagger:dagger-android-processor:2.10'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
}

如果你的项目中未使用v4包的Fragment与v7包的AppCompatActivity的话 可以去掉

compile 'com.google.dagger:dagger-android-support:2.11-rc2'

demo:现在我们要做一个coffee贩卖的app,需求是这样的
coffee全球定价都是一致的 为1RMB 但是不同的国家价格不同

中国区是1CNY
这里写图片描述

美国区售价1USD
这里写图片描述

欧洲区售价1EUR
这里写图片描述

其他区售价1RMB
这里写图片描述

好了 我们可以来编写代码了
首先我们新建个Coffee类 里面就是设置coffee的价格

public class Coffee {
    public String price(){//全球统一定价
        return "1RMB";
    }
}

新建App的Application

//dagger-android 与dagger-android-support中都有DaggerApplication
//不同的是support中的是会自动对v4包中的Fragment进行注入,本demo
//是用了ViewPager+Fragment  所以选择dagger-android-support中的
//DaggerApplication作为基类
public class App extends DaggerApplication{
    //DaggerApplication abstract method
     @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        //return null;
        //当我们App的Component写好后
        return DaggerApp_Component.builder().create(this);
    }
    //代码编写

    //创建CoffeeModule  全球统一售价
    //也可以在MainActivity中创建CoffeeModule
    //那么App的Component的modules中就不能包含CoffeeModule
     @dagger.Module
    public static class CoffeeModule{
        @Provides
        public Coffee provideCoffee(){
            return new Coffee();
        }
    }
    //创建App的Component
      @dagger.Component(modules = {
            AndroidSupportInjectionModule.class,
            AndroidInjectionModule.class,
            CoffeeModule.class,
            /*activity inject*/
            MainActivity.Module.class
    })
    public interface Component extends AndroidInjector<App>{
        @dagger.Component.Builder
        public abstract class Builder extends AndroidInjector.Builder<App>{
            //这个就是我们以前在dagger2中提供module的方法  
            public abstract Builder coffeeModule(CoffeeModule coffeeModule);

            //重载这个函数保存我们需要new的module
            @Override
            public void seedInstance(App instance) {
                coffeeModule(new CoffeeModule());
            }
        }
    }

}

当代码完成后 你可能会发现MainActivity不存在,不要急,这个为什么要写在这里呢,不要急 等下我把Activity代码写完就来解释

看上面发的图 你能看到每个界面中底部都有全球统一售价1RMB 这个是在Activity中获取coffee的价格进行显示的
以下是Activity代码

/*DaggerAppCompatActivity  是support包中的注入基类*/
public class MainActivity extends DaggerAppCompatActivity {
    @dagger.Module(subcomponents = {
            Component.class
    })
    public abstract class Module{
        @Binds
        @IntoMap
        @ActivityKey(MainActivity.class)
        public abstract AndroidInjector.Factory<? extends Activity> bind(Component.Builder builder);
    }

    @dagger.Subcomponent(modules = {
            CoffeeFragment.Module.class//这一句可以写到App的Component的modules中 但是如果在app中的话  那么CoffeeFragment.Module中的东西将是单例  在Activity中 随着Activity销毁  CoffeeFragment的数据也将销毁
    })
    public interface Component extends AndroidInjector<MainActivity>{
        @dagger.Subcomponent.Builder
        public abstract class Builder extends AndroidInjector.Builder<MainActivity>{}
    }

    @Inject
    Coffee coffee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView(R.id.coffeePrice).setText("全球统一售价:" + coffee.price());
        setupCoffees();
    }

    private void setupCoffees(){
        final List<Fragment> fragments = new ArrayList<>();
        fragments.add(CoffeeFragment.newInstance(1));
        fragments.add(CoffeeFragment.newInstance(2));
        fragments.add(CoffeeFragment.newInstance(3));
        fragments.add(CoffeeFragment.newInstance(4));

        ((ViewPager)findViewById(R.id.viewPager)).setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }

            @Override
            public int getCount() {
                return fragments.size();
            }

            @Override
            public CharSequence getPageTitle(int position) {
                String title = "";
                switch (position){
                    case 0:
                        title = "中国";
                        break;
                    case 1:
                        title = "美国";
                        break;
                    case 2:
                        title = "欧洲";
                        break;
                    case 3:
                        title = "其他";
                        break;
                }
                return title;
            }
        });

        ((TabLayout)findViewById(R.id.tabLayout)).setupWithViewPager(((ViewPager)findViewById(R.id.viewPager)));
    }

    public TextView textView(int id){
        return (TextView) findViewById(id);
    }
}

CoffeeFragment代码

//这里的DaggerFragment是dagger-android-support的DaggerFragment
//有的版本中叫DaggerSupportFragment
public class CoffeeFragment extends DaggerFragment{
    @dagger.Module
    public static class FragmentModule{
    //由于AppModule中提供了Coffee
    //CoffeeFragment依赖与MainActivity
    //MainActivity依赖于App  
    //所以@Inject Coffee是有对象的
    //因此我们在这里用@Named使用fragment中新建的Coffee
        @Provides
        @Named("country")
        public Coffee provideCoffee(){
            return new CountyCoffee();
        }
    }

    @dagger.Module(subcomponents = {
            Component.class
    })
    public abstract class Module{
        @Binds
        @IntoMap
        @FragmentKey(CoffeeFragment.class)
        public abstract AndroidInjector.Factory<? extends Fragment> bind(CoffeeFragment.Component.Builder builder);
    }

    @dagger.Subcomponent(modules = {
            FragmentModule.class
    })
    public interface Component extends AndroidInjector<CoffeeFragment>{
        @dagger.Subcomponent.Builder
        public abstract class Builder extends AndroidInjector.Builder<CoffeeFragment>{
            public abstract Builder fragmentModule(FragmentModule module);

            @Override
            public void seedInstance(CoffeeFragment instance) {
                fragmentModule(new FragmentModule());
            }
        }
    }

    public static Fragment newInstance(int index){
        CoffeeFragment fragment = new CoffeeFragment();
        return fragment;
    }

    @Inject
    @Named("country")
    Coffee coffee;

    private View rootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (rootView == null){
            rootView = inflater.inflate(R.layout.fragment_coffee,null);
            textView(R.id.coffeePrice).setText(coffee.price());
        }
        return rootView;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (rootView.getParent() != null){
            ((ViewGroup)rootView.getParent()).removeView(rootView);
        }
    }

    public TextView textView(int id){
        return (TextView) rootView.findViewById(id);
    }
}

CountryCoffee代码

public class CountyCoffee extends Coffee{
    private String price;
    private static int index = 0;
    public CountyCoffee(){
        switch (index){
            case 0:
                price = "1CNY";
                break;
            case 1:
                price = "1USD";
                break;
            case 2:
                price = "1EUR";
                break;
            case 3:
                price = "1RMB";
                break;
        }
        index++;
    }
    @Override
    public String price() {
        return price;
    }
}

好了 我们来解释下App中Component的modules的 MainActivity.Module.class
说白了 这个就是告诉App MainActivity依赖App的Component 所以在MainActivity中可以@Inject Coffee coffee; 同理 MainActivity中的CoffeeFragment.Module.class也是一样的道理 不能写在Application中的原因是App只会创建一次 如果写App里面就是单例了 ,本例写App中和MainActivity中都是可以的 但是推荐写在Activity中 这样生命周期就对应了

其他说明

dagger2-android最新版可以自动注入很多类 下面列出来能注入对象的基类
DaggerApplication dagger-android基础包
DaggerActivity
DaggerBroadcastReceiver
DaggerContentProvider
DaggerFragment dagger-android基础包 不是v4的Fragment
DaggerIntentService
DaggerService

DaggerAppCompatActivity
DaggerApplication 支持v4的 一般来说 现在的都用这个最好
DaggerFragment 支持v4包的fragment的注入基类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值