Dagger2相关知识-二、Dagger2使用

时间:2024-03-28 20:30:34

使用Dagger2依赖注入Coffee----------探索如何实现Coffee全局单例注入的过程

2.1 非单例

依然按照上面的demo,测试一下注入两个类一样的对象,观察哈希值判断是否单例

Coffee

public class Coffee {
    public Coffee() {

    }
}

CoffeeModule

@Module
public class CoffeeModule {
    @Provides
    public Coffee GetCoffee() {
        return new Coffee();
    }
}

CoffeeComponent

@Component(modules = {CoffeeModule.class})
public interface CoffeeComponent {

    void injectActivity_first(Activityfirst activityfirst );

    void injectActivity_second(Activitysecond activitysecond );
}

Activityfirst

public class Activityfirst extends AppCompatActivity implements View.OnClickListener {
    Button button;
    @Inject
    Coffee coffee1;
    @Inject
    Coffee coffee2;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activityfirst);
        button = findViewById(R.id.Button_1);
        button.setOnClickListener(this::onClick);

        //方式一
//        DaggerCoffeeComponent.builder()
//                .coffeeModule(new CoffeeModule()).build()
//                .injectActivity_first(this);
//

        //方式二
        DaggerCoffeeComponent.create().injectActivity_first(this);
        Log.d("Henry", " ------" + coffee1.hashCode());
        Log.d("Henry", " ------" + coffee2.hashCode());
    }

    @Override
    public void onClick(View v) {
        startActivity(new Intent(this, Activitysecond.class));
    }

}

测试结果:
在这里插入图片描述
很明显,两个对象哈希值不同,默认不是单例实现。

2.2 局部单例

使用@Singleton注解实现局部单例
Coffee不变

public class Coffee {
    public Coffee() {

    }
}

CoffeeModule 方法添加@Singleton

@Module
public class CoffeeModule {
    @Singleton
    @Provides
    public Coffee GetCoffee() {
        return new Coffee();
    }
}


CoffeeComponent 接口添加@Singleton

@Singleton
@Component(modules = {CoffeeModule.class})
public interface CoffeeComponent {

    void injectActivity_first(Activityfirst activityfirst );

    void injectActivity_second(Activitysecond activitysecond );
}

Activityfirst不变

public class Activityfirst extends AppCompatActivity implements View.OnClickListener {
    Button button;
    @Inject
    Coffee coffee1;
    @Inject
    Coffee coffee2;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activityfirst);
        button = findViewById(R.id.Button_1);
        button.setOnClickListener(this::onClick);

        //方式一
//        DaggerCoffeeComponent.builder()
//                .coffeeModule(new CoffeeModule()).build()
//                .injectActivity_first(this);
//

        //方式二
        DaggerCoffeeComponent.create().injectActivity_first(this);
        Log.d("Henry", " ------" + coffee1.hashCode());
        Log.d("Henry", " ------" + coffee2.hashCode());
    }

    @Override
    public void onClick(View v) {
        startActivity(new Intent(this, Activitysecond.class));
    }

}

Activitysecond

public class Activitysecond extends AppCompatActivity {

    @Inject
    Coffee coffee3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activitysecond);

        //方式一
//        DaggerCoffeeComponent.builder()
//                .coffeeModule(new CoffeeModule()).build()
//                .injectActivity_second(this);
//

        //方式二
        DaggerCoffeeComponent.create().injectActivity_second(this);
        Log.d("Henry", " ------" + coffee3.hashCode());
    }


}

测试结果:同一个Activity下哈希值一致,但是再另一个Activity又重新实例化对象,局部单例。
在这里插入图片描述

2.3 全局单例

如何实现全局单例?局部单例搭配application实现
局部单例代码不变,添加application和修改CoffeeComponent初始化形式
SingletonApplication

public class SingletonApplication extends Application {
    private CoffeeComponent myCoffeeComponent;


    @Override
    public void onCreate() {
        super.onCreate();
        myCoffeeComponent = DaggerCoffeeComponent.builder()
                .coffeeModule(new CoffeeModule())
                .build();
    }

    public CoffeeComponent getMyCoffeeComponent() {
        return myCoffeeComponent;
    }


}

Activityfirst

public class Activityfirst extends AppCompatActivity implements View.OnClickListener {
    Button button;
    @Inject
    Coffee coffee1;
    @Inject
    Coffee coffee2;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activityfirst);
        button = findViewById(R.id.Button_1);
        button.setOnClickListener(this::onClick);
        //方式三

        ((SingletonApplication)getApplication())
                .getMyCoffeeComponent()
                .injectActivity_first(this);

        Log.d("Henry", " ------" + coffee1.hashCode());
        Log.d("Henry", " ------" + coffee2.hashCode());

    }

    @Override
    public void onClick(View v) {
        startActivity(new Intent(this, Activitysecond.class));
    }

}

Activitysecond

public class Activitysecond extends AppCompatActivity {

    @Inject
    Coffee coffee3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activitysecond);
        
        //方式三
        ((SingletonApplication) getApplication())
                .getMyCoffeeComponent()
                .injectActivity_second(this);

        Log.d("Henry", " ------" + coffee3.hashCode());
    }
}

测试结果:哈希值一致了。
在这里插入图片描述

如果工程很大,需要代码解耦和单例,完全可以使用这种方法满足对应场景。