Dagger2 再菜鸟入门

        想放两个链接,是我最初对dagger2的理解,也许对你有帮助:

         一些关于dagger2的理解(一)      一些关于dagger2的理解(二)   

         刚刚开始接触Dagger2的时候,肯定是一脸蒙圈,尤其是对于那些不熟悉注解的程序员来说,更是感觉像天书一般“迷人”。
         Dagger2最初给人的印象是很华丽的:尤其是在初级的示例中,一组provide 、Module、Component提供的仅仅是一个无参实体类的初始化,好大一头奶牛只挤出一滴优酸乳。
         我个人理解它是这样的:
         本质:注解框架;
         目的:全新的实例初始化方式(体系);
         优势:统一配置,方便复用(但要注意单例等);
         劣势:小项目不是很实用
 
先说优势:
         假如你买矿泉水,现在的国家标准是满足一条标准的就允许出售(具体最多几条,谁知道),矿泉水是这样的:

public class KuangquanWater {
    private String norm;

    public KuangquanWater(String norm) {
        this.norm = norm;
    }

    public String show(){
        return norm;
    }
}

        普通情况下是这样的:

public class Consume {
    KuangquanWater m = new KuangquanWater("透明度");
}
        Dagger2是这样的:
@Module
public class WaterModule{
    public KuangquanWater getWaterOne(){
        return new KuangquanWater("透明度");
    }
}
@Component(modules = WaterModule.class)
public interface WaterComponent{
    void inject(Consume c);
}

public class Consume {
    @Inject
    KuangquanWater m; 
    void onCreate(){
        DaggerWaterComponent.builder().build().inject(this);
    }

}

         握了颗草,一个初始化搞了这么多幺蛾子,要折寿啊!
         如果有一百个人要买这种水,需要一百个Component去包装水。那么这个时候问题来了:如果我标准变了,要求水质必须有两个标准符合,成了这样:

public class KuangquanWater {
    private String norm1;
    private String norm2;

    public KuangquanWater(String norm1,String norm2) {
        this.norm1 = norm1;
        this.norm2 = norm2;
    }

    public String show(){
        return norm1+"+"+norm2;
    }
}

         按照普通情况,如果有100个实例化,我要改100个实例化的地方,想想就  法克(汉语发音) 了!
         而dagger只需要这样:

@Module
public class WaterModule{
    public KuangquanWater getWaterOne(){
        return new KuangquanWater("透明度","矿物质含量");
    }
}

         只修改一个地方,1000个都可以不用管了。
         就问你怕不怕!当然实际应用数量不可能这么夸张,但是构造方法的复杂度会增加,也不是这里这么简单了。意义依旧重大的不要不要的。




Dagger2的注解:
 
         @Provide(用于注解方法) 标注某个返回类型的get方法,声明该类型可用并在后面会被用到;
         @Module(用于注解类) 用来包含@Provide提供的类型,起到一个包装的作用;
         @Component(用于注解类) 把@Module的包装集合起来,供某个类使用;
         @Inject(用于注解变量) 在集合中所有包含的@Provide进来的找相同类型;
 
         我还是喜欢打个粗俗的比喻,饿了想吃包子,点个外卖吧:想吃什么馅(@Inject)自己是知道的。而包子店里的馅(@Provider)是要放进包子(@Module)的,包子是怎么到手里的?快递(Build得到的DaggerXXComponent)把各种包子的包裹(@Component)送过来的。如果你想吃好几种口味好几种馅(多个@Inject),可能就需要买多个包子(@Component=(modules={aModule.class,bModule.class…}))了;
        
         来,咱么走一趟,边写边说。
         打算做这么个小项目:计算两个人的缘分值。
         要用到的算法就是:两个名字的hashCode按比例相加,然后模100,就是圆粪值。
1.      先新建个项目,名字随便起
2.      Project的build.gradle添加如下:



        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

3.      在module的build.gradle添加如下两处:



apply plugin: 'com.neenbedankt.android-apt'

compile 'com.google.dagger:dagger:2.5'
apt 'com.google.dagger:dagger-compiler:2.5'
provided 'org.glassfish:javax.annotation:10.0-b28'

4.      准备三个实体类:

public class People {
    private int ratio;//计算比例

    public People(int ratio) {
        this.ratio = ratio;
    }

    public int getScore(String name){
        return name.hashCode()*ratio/10;
    }
}

public class Man extends People{

    public Man(int rote) {
        super(rote);
    }

    public Man(){
        this(6);
    }
}

public class Woman extends People {
    public Woman(int rote) {
        super(rote);
    }

    public Woman(){
        this(4);
    }
}

         接下来是重点了


5.      做馅,包包子(@Provide和@Module)

/**
 * Created by ShuaiZhang on 2016/9/29.
 */
@Module
public class PeopleModule {
    @Provides
    Woman getWoman(){
        return new Woman(8);//自由指定
    }

    @Provides
    Man getMan(){
        return new Man(8);//自由指定
    }

    @Provides @Named("nv")// 存在同样的两个People,就需要@Named来区分
    People getNv(){
        return new Woman();
    }

    @Provides @Named("nan")
    People getNan(){
        return new Man();
    }
}

 
         其实分开两个来比较好,但是我懒……
6.      打包上面的包子

@Component(modules = PeopleModule.class)//没错,我就是打包
public interface PeopleComponent {
    void inject(MainActivity m);//指定客户
}

         菜单栏BuildàRebuild Project一下。
7.      干掉到手的包子
         先上布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.shazeys.yinyuan.MainActivity">

    <TextView
        android:layout_marginTop="15dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="男名:" />
    <EditText
        android:id="@+id/edt_man"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="女名:" />
    <EditText
        android:id="@+id/edt_woman"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


    <TextView
        android:id="@+id/txt_score"
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="得分:无" />
    <Button
        android:id="@+id/btn_compute"
        android:text="计算"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

         MainActivity.class:

public class MainActivity extends AppCompatActivity {

    @Inject
    Woman woman;
    @Inject
    Man man;

    EditText edtNan;
    EditText edtNv;
    TextView txtScore;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerPeopleComponent.builder()//接收到外卖了
                .build()
                .inject(this);
        edtNan = (EditText) findViewById(R.id.edt_man);
        edtNv = (EditText) findViewById(R.id.edt_woman);
        txtScore = (TextView) findViewById(R.id.txt_score);
        Button btnCompute = (Button) findViewById(R.id.btn_compute);

        btnCompute.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkInput())
                    compute();
            }
        });
    }

    /**
     * 计算得分并显示
     */
    private void compute() {
        int nan = man.getScore(edtNan.getText().toString());
        int nv = woman.getScore(edtNv.getText().toString());
        int result = (nan+nv)%100;
        txtScore.setText("得分:"+result);
    }

    /**
     * 判断输入值
     * @return
     */
    boolean checkInput(){
        if (edtNan.getText().toString().equals("")){
            showToast("请输入男名");
            return false;
        }
        if (edtNv.getText().toString().equals("")){
            showToast("请输入女名");
            return false;
        }
        return true;
    }

    void showToast(String tip){
        Toast.makeText(this,tip,Toast.LENGTH_SHORT).show();
    }
}

 

         到这里就可以运行看效果了。

         不过,最好还是把包子里刚刚留的坑也处理一下,修改MainActivity.class的代码(只显示修改部分,其他均不变):


         用@Named来区分相同的@Provide。

 

        赶时髦,代码放到了我的Github上:地址链接

         最后声明:本计算不含任何科学或者迷信依据,请勿相信,请勿较真。









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公贵买其鹿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值