Dagger2 高级特性使用与实现分析(二)

版权声明:转载请标明出处 https://blog.csdn.net/panyongjie2577 https://blog.csdn.net/panyongjie2577/article/details/89333460

Component依赖

创建注入类

public class RetrofitManager {
    public Retrofit retrofit;
    private static final String BASE_URL = "https://api.apiopen.top";
    
    @Inject
    public RetrofitManager(){
        retrofit = new Retrofit
                   .Builder()
                   .baseUrl(BASE_URL)
                   .addConverterFactory(
                       GsonConverterFactory.create())
                   .build();
    }
}

创建Module类

@(android)Module
public class HttpActivityModule {
    private int cacheSize;
    public HttpActivityModule(int cacheSize){
        this.cacheSize = cacheSize;
    }
    
    @Provides
    RetrofitManager provideRetrofitManager(){
        return new RetrofitManager();
    }
}

创建Component类

@Component(modules = HttpActivityModule.class)
public interface CommonHttpActivityComponent {
    RetrofitManager getRetrofitManager();
}

创建Compent依赖类

@Component(dependencies = CommonHttpActivityComponent.class)
public interface HttpFragmentComponent {
    void inject(ThirdFragment thirdFragment);
}

创建Activity类

public class ThirdActivity extends AppCompatActivity {

    @BindView(R.id.containerLayout)
    LinearLayout containerLayout;

    CommonHttpActivityComponent commonHttpActivityComponent;

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

        ButterKnife.bind(this);

        commonHttpActivityComponent = 
           DaggerCommonHttpActivityComponent.builder()
           .httpActivityModule(new HttpActivityModule(100))
           .build();

        ThirdFragment thirdFragment = new ThirdFragment();

        FragmentTransaction fragmentTransaction = 
           getFragmentManager().beginTransaction();
        fragmentTransaction.add(
		   R.id.containerLayout, thirdFragment);
        fragmentTransaction.commit();

        containerLayout.setBackgroundColor(
		   Color.parseColor("#0099ff"));
    }

    public CommonHttpActivityComponent 
		    getCommonHttpActivityComponent(){
        return commonHttpActivityComponent;
    }
}

创建Fragment类

public class ThirdFragment extends Fragment {
    private View view;

    @Inject
    RetrofitManager retrofitManager;
    PoetryAPI poetryAPI;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             Bundle savedInstanceState)
    {
        super.onCreateView(inflater, 
                           container, savedInstanceState);

        if(null == view){
            view = inflater.inflate(
	            R.layout.second_fragment, null);

            //这里必须进行绑定
            ButterKnife.bind(this, view);

            CommonHttpActivityComponent component =
                      ((ThirdActivity)getActivity())
                        .getCommonHttpActivityComponent();

            DaggerHttpFragmentComponent.builder()
                    .commonHttpActivityComponent(
                        commonHttpActivityComponent)
                    .build()
                    .inject(this);

            poetryAPI = retrofitManager
                .retrofit.create(PoetryAPI.class);

            refershData(1);
        }
        return  view;
    }
}

SubComponent

使用多个SubComponent

创建Presenter

public class WechatPayPresenter {
    //余额
    private double accoutAmount;

    @Inject
    public WechatPayPresenter(double accoutAmount){
        this.accoutAmount = accoutAmount;
    }

    //是否可以进行支付
    public boolean doPay(double money){
        return accoutAmount >= money;
    }

    //显示余额
    public double getAccoutAmount(){
        return accoutAmount;
    }
}

public class UnionPayPresenter {
    //余额
    private double accoutAmount;

    @Inject
    public UnionPayPresenter(double accoutAmount){
        this.accoutAmount = accoutAmount;
    }

    //是否可以进行支付
    public boolean doPay(double money){
        return accoutAmount >= money;
    }

    //显示余额
    public double getAccoutAmount(){
        return accoutAmount;
    }
}

创建Module

@Module
public class WechatPayModule {
    private double accoutAmount;

    public WechatPayModule(double accoutAmount) {
        this.accoutAmount = accoutAmount;
    }

    @Provides
    public WechatPayPresenter provideWechatPayPresenter(){
        return new WechatPayPresenter(accoutAmount);
    }
}

@Module
public class UnionPayModule {
    private double accoutAmount;
    public UnionPayModule(double accoutAmount) {
        this.accoutAmount = accoutAmount;
    }

    @Provides
    public UnionPayPresenter provideUnionPayPresenter(){
        return new UnionPayPresenter(accoutAmount);
    }
}

创建Subcomponent

@Subcomponent
public interface WechatPayComponent {
    void inject(SubComponentActivity subComponentActivity);
}

@Subcomponent
public interface UnionPayComponent {
    void inject(SubComponentActivity subComponentActivity);
}

创建Component

@Component(modules = {WechatPayModule.class, UnionPayModule.class})
public interface CommonPayComponent {
    WechatPayComponent getWechatPayComponent();
    UnionPayComponent getUnionPayComponent();
}

使用Subcomponent

public class SubComponentActivity extends AppCompatActivity{

  @Inject
  WechatPayPresenter wechatPayPresenter;

  @Inject
  UnionPayPresenter unionPayPresenter;

  Unbinder unbinder;

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

      unbinder = ButterKnife.bind(this);

	  //Component构建
      CommonPayComponent commonpayComponent = 
              DaggerCommonPayComponent.builder()
              .wechatPayModule(new WechatPayModule(10000))
              .unionPayModule(new UnionPayModule(28000))
              .build();

      //进入Subcomponent注入操作
      commonpayComponent
         .getWechatPayComponent().inject(this);
      commonpayComponent
         .getUnionPayComponent().inject(this);
  }

  @OnClick({R.id.wechatPayButton, R.id.unionPayButton})
  public void onViewClicked(View v) {
      switch (v.getId())
      {
          case R.id.wechatPayButton:
              if(null == wechatPayPresenter) {
                  showMessage("微信支付不可用 !!");
                  return;
              }

              boolean result = wechatPayPresenter.doPay(12000);
              if(result){
                  showMessage("微信支付成功!!");
              }else{
                  showMessage("账户余额" + 
                      wechatPayPresenter.getAccoutAmount()
                          + "元,微信支付失败!!");
              }
              break;
          case R.id.unionPayButton:
              if(null == unionPayPresenter) {
                  showMessage("银联支付服务不可用!!");
                  return;
              }

              result = unionPayPresenter.doPay(12000);
              if(result){
                  showMessage("银联支付成功!!");
              }else{
                  showMessage("账户余额" + 
                        unionPayPresenter.getAccoutAmount()
                        + "元,银联支付失败!!");
              }
              break;
      }
  }

  private void showMessage(String message)
  {
      Toast.makeText(SubComponentActivity.this, 
         message, Toast.LENGTH_LONG).show();
  }

  @Override
  public void onDestroy(){
      super.onDestroy();
      if(null != unbinder){
          unbinder.unbind();
      }
  }
}

Subcomponent 关联module并进行赋值

定义Presenter

public class WalletPayPresenter {
    //余额
    private double accoutAmount;

    @Inject
    public WalletPayPresenter(double accoutAmount)
    {
        this.accoutAmount = accoutAmount;
    }

    //是否可以进行支付
    public boolean doPay(double money)
    {
        return accoutAmount >= money;
    }

    //显示余额
    public double getAccoutAmount()
    {
        return accoutAmount;
    }
}

定义Module

@Module
public class WalletPayModule {
    private double accoutAmount;

    public WalletPayModule(double accoutAmount) {
        this.accoutAmount = accoutAmount;
    }

    @Provides
    public WalletPayPresenter provideWalletPayPresenter() {
        return new WalletPayPresenter(accoutAmount);
    }
}

定义Subcomponent

@Subcomponent(modules = {WalletPayModule.class})
public interface WalletComponent {
    void inject(WalletActivity walletActivity);

	//用@Subcomponent.Builder来定义接口类,用于实现Module的注入操作。
	//******这里必须使用Builder作为接口名否则编译不通过*******
    @Subcomponent.Builder
    interface Builder {
        Builder loadModule(WalletPayModule walletPayModule);
        WalletComponent build();
    }
}

定义Component

@Component
public interface UserWalletComponent {
    WalletComponent.Builder componentBuilder();
}

测试@Subcomponent赋值

public class WalletActivity extends AppCompatActivity{

    @Inject
    WalletPayPresenter walletPayPresenter;

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

        DaggerUserWalletComponent.Builder builder = 
          DaggerUserWalletComponent.builder();
          
        WalletComponent.Builder walletComponentBuilder = 
          builder.build().componentBuilder();
        
        WalletPayModule walletPayModule = 
            new WalletPayModule(15000);
            
        WalletComponent walletComponent = 
	        walletComponentBuilder.
	        loadModule(walletPayModule).build();
	        
        walletComponent.inject(this);

        if(null == walletPayPresenter) {
            showMessage("walletPayPresenter is null !!");
            return;
        }

        boolean result = walletPayPresenter.doPay(12000);
        if(result){
            showMessage("钱包支付成功!!");
        }else{
            showMessage("钱包余额" + 
                walletPayPresenter.getAccoutAmount()
                    + "元,钱包支付失败!!");
        }
    }

    private void showMessage(String message) {
        Toast.makeText(WalletActivity.this, message, 
           Toast.LENGTH_LONG).show();
    }
}

Scope

Scope是什么

标识一个作用域标签。一个作用域标签应用在一个可以被注解构建的类上,
并对如何注解复用实例的实例进行管理。

默认情况下,如果不提前使用scope标签,在使用注解创建一个实例(根据实例的构建函数来进行注解),
每一次进行注解的使用都需要使用一个实例,注解完成后,这个示例就会被遗忘掉。

如果提前使用了scope标签,注解器会将实例保存起来,为下一次注解时就可以复用这个实例。
在多线程中可以操作一个已经有作用域的实例,它们的实现是非线程安全的。

实现scope标签本身就留给注解器来完成了。

Singleton作用域注解

无module示例

@Singleton
public class PayResult {
    @Inject
    public PayResult(){}
}

@Singleton
@Component
public interface PayComponment {
    void inject(WechatPayActivity wechatPayActivity);
}

public class WechatPayActivity extends AppCompatActivity {
    @Inject
    PayResult payResult;

    @Inject
    PayResult payResult1;

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

        DaggerPayComponment.builder()
                .build().inject(this);

        if(null != payResult && null != payResult1) {
            String log = String.valueOf("hashCode: " +   
                           payResult.hashCode()) + " -- " +
	                     String.valueOf("hashCode1: " + 
		                   payResult1.hashCode());
            Toast.makeText(WechatPayActivity.this, log,
                    Toast.LENGTH_LONG).show();

            Log.i("Pay", log);
        }
    }
}    

运行程序,日志打印: hashCode: 130730013 – hashCode1: 130730013,
我们这里对PayResult注解了两次,但是因为我们使用了@Sigleton注解来约束它的作用为单例,所以两个PayResult的实例对象都为同一个对象,他们的hashCode都是相同的,说明@Singleton注解起作用了。

有module示例

@Singleton
public class PayResult {
    @Inject
    public PayResult(){}

    private int setResultCode;

    public int getSetResultCode() {
        return setResultCode;
    }

    public void setSetResultCode(int setResultCode) {
        this.setResultCode = setResultCode;
    }
}

@Module
public class PayModule {
    @Singleton
    @Provides
    public PayResult provideIBaseView()
    {
        PayResult payResult = new PayResult();
        payResult.setSetResultCode(
				        (int)((Math.random() * 100)));
        return  payResult;
    }
}

@Singleton
@Component(modules = PayModule.class)
public interface PayComponment {
    void inject(WechatPayActivity wechatPayActivity);
}

public class WechatPayActivity extends AppCompatActivity {
    @Inject
    PayResult payResult;

    @Inject
    PayResult payResult1;

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

        DaggerPayComponment.builder()
                .build().inject(this);

        if(null != payResult && null != payResult1)
        {
            String log = String.valueOf("hashCode: " +   
                           payResult.hashCode()) + " -- " +
	                     String.valueOf("hashCode1: " + 
		                   payResult1.hashCode());
            Toast.makeText(WechatPayActivity.this, log,
                    Toast.LENGTH_LONG).show();

            Log.i("Pay", log);

			 String log1 = String.valueOf("resultCode: " +   
			          payResult.getSetResultCode()) + " -- " +
                  String.valueOf("resultCode1: " + 
                      payResult1.getSetResultCode());
            Log.i("Pay", log1);
        }
    }
}

运行程序,日志打印:

hashCode: 219754701 -- hashCode1: 219754701
resultCode: 13 -- resultCode1: 13

我们这里对PayResult注解了两次,但是因为我们使用了@Sigleton注解来约束它的作用为单例,所以两个PayResult的实例对象都为同一个对象,他们的hashCode和resultCode都是相同的,说明@Singleton注解起作用了。

自定义Scope

自定义一个Scope注解接口

@Scope       //表明这是一个作用域接口
@Singleton   //使用单例
@Retention(RetentionPolicy.RUNTIME)  //在运行时中进行保留
public @interface SingleTonScope {

}

使用自定义Scope

将上面测试代码中的所有Singleton替换为SingleTonScope即可,示例如下

@SingleTonScope
public class PayResult {
    @Inject
    public PayResult(){}
    
    private int setResultCode;

    public int getSetResultCode() {
        return setResultCode;
    }

    public void setSetResultCode(int setResultCode) {
        this.setResultCode = setResultCode;
    }
}

@Module
public class PayModule {
    @SingleTonScope
    @Provides
    public PayResult provideIBaseView(){
        PayResult payResult = new PayResult();
        payResult.setSetResultCode(
				        (int)((Math.random() * 100)));
        return  payResult;
    }
}

@SingleTonScope
@Component(modules = PayModule.class)
public interface PayComponment {
    void inject(WechatPayActivity wechatPayActivity);
}

测试类WechatPayActivity还是和上面一样, 直接运行程序,日志输出如下, 发现我们的自定义Scope已经发生了作用,同样可以实现单例作用域效果。

扫描二维码关注公众号,回复: 5914079 查看本文章
hashCode: 176287840 -- hashCode1: 176287840
resultCode: 21 -- resultCode1: 21

猜你喜欢

转载自blog.csdn.net/panyongjie2577/article/details/89333460