Dagger2 explore the mind 3-- two advanced components (a)

       Today @Scope talk about this component. Why it is an advanced component, because it is basically no effect, but after understanding the basic components must also be used.

       Scope scope mean, in general it used to mark @Provide method, the generated object unit of the embodiment. But @Scope not be used directly, we need to achieve. The default implementation has @Singleton.

A local singleton

       Saying that thousands of sentences, as two lines of code.

       Directly on the code is not changed in the original code, from a separate Activity, named SecondActivity.

public class SecondActivity extends AppCompatActivity {
@BindView(R.id.second_text_1) TextView text1;
@BindView(R.id.second_text_2) TextView text2;
@BindView(R.id.second_text_3) TextView text3;
@BindView(R.id.second_text_4) TextView text4;

@Inject Coffee coffee1;
@Inject Coffee coffee2;
@Inject Tools tool1;
@Inject Tools tool2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
ButterKnife.bind(this);

SecondComponent component = DaggerSecondComponent.builder()
.secondModule(new SecondModule())//添加Module
.build();

coffee1 = component.coffee();
coffee2 = component.coffee();
tool1 = component.tools();
tool2 = component.tools();

text1.setText(coffee1.toString());
text2.setText(coffee2.toString());
text3.setText(tool1.toString());
text4.setText(tool2.toString());
}
}

       Then the Layout named second.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/second_text_1"
/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/second_text_2"
/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/second_text_3"
/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/second_text_4"
/>

</LinearLayout>

        Tools used, and this time we to drink Coffee.

public class Coffee {
    public Coffee(){};
}

        In fact, nothing changes, and not before the main code obfuscation, affect the understanding.

        Always remember, a stage is over, it is necessary to change the starting point again.

        The following is a Module and Component:

@Module
public class SecondModule {

@Singleton
@Provides
Coffee provideCoffee(){
return new Coffee();
}

@Provides
Tools provideTools(){
return new Tools();
}
}
@Singleton
@Component(modules = SecondModule.class)
public interface SecondComponent {
Coffee coffee();

Tools tools();
}

          Careful reading of these small partners will find the code, this Component, there's no write inject () method!

          Yes, I remember I said earlier, before using inject () method returns a Component.

          Also standard is a test center, I can not remember the junior partner rebuilt again chap.

          So this is a call to the manual method Component assignment.

          Finally, add a jump in MainActivity Button, layout I have not posted the code to see more hair loss.

    @OnClick({R.id.turn_firstactivity,R.id.turn_secondactivity})
    public void onViewClicked(View view) {
        switch (view.getId()){
            case R.id.turn_firstactivity:
                startActivity(new Intent(this, FirstActivity.class));
                break;
            case R.id.turn_secondactivity:
                startActivity(new Intent(this, SecondActivity.class));
                break;
        }
    }

          Is not suddenly discovered the benefits of ButterKnife, simplifying large part of the code, click directly on the id event, do not control is not Button.

          We take a look at DaggerComponen to changes in the source code.

  private void initialize(final Builder builder) {

    this.provideCoffeeProvider =
        DoubleCheck.provider(SecondModule_ProvideCoffeeFactory.create(builder.secondModule));

    this.provideToolsProvider = SecondModule_ProvideToolsFactory.create(builder.secondModule);
  }

  @Override
  public Coffee coffee() {
    return provideCoffeeProvider.get();
  }

  @Override
  public Tools tools() {
    return provideToolsProvider.get();
  }

        Component override the two methods, and the examples of each corresponding class factory corresponding direct return get () method.

        Run it and found the result is

        @Singleton tagged with two consistent hashing address Coffee @Provide example, as the same object. (Interested children can change a member variable of a class to see if the other will not change.)

        @Singleton is this useful, locally called the singleton. Note that not a single case of a global, just in the same Activity is the same across Activity is different.

        Note that use of @Module @Provide @Singleton labeled binding @Component, @ Component mark @Singleton also, it represents a single @Component there @Singleton Example.

        This sentence is about, Duokanjibian understand.

        As for how to achieve a single case, we look at the source.

    this.provideCoffeeProvider =
        DoubleCheck.provider(SecondModule_ProvideCoffeeFactory.create(builder.secondModule));

    this.provideToolsProvider = SecondModule_ProvideToolsFactory.create(builder.secondModule);

       The problem lies in the DoubleCheck above, interested friends can go and see DoubleCheck realize source, I'm too lazy, too lazy to speak.

       Well, since @Singleton is a local single case, how to achieve global single case of it? Then speaking.

Two global singleton

       As mentioned above, @ Scope is a region of action, we are using the instantiation in the Activity, it is a partial Activity in the single embodiment. So the singleton global must be instantiated in the Application.

       Let's write their Application to inject dependencies.

public class MyApplication extends Application {

    private static GlobalComponent component;

    @Override
    public void onCreate() {
        super.onCreate();

        component = DaggerGlobalComponent.builder()
                .globalModule(new GlobalModule())
                .build();
    }

    GlobalComponent get(){
        return component;
    }
}

         Because rewrite the Application, you need to add it into the Manifiest

    <application
        android:name="MyApplication"
        ......
    </application>

        Application to the global injection, very clearly written in front, directly attached to the code behind.

        Again a class Global, Globalization point.

public class Global {
    public Global(){};
}

        Component:

@Component(modules = GlobalModule.class)
public interface GlobalComponent {

    Global global();

}

         Module:

@Module
public class GlobalModule {

    @Provides
    Global provideGlobal(){
        return new Global();
    }

}

       If the previous good attendance of students, should now be able to read the. We inject an instance of a Component in the MyApplication, and wrote a get () method to get it.

       Subsequent need to directly obtain MyApplication Examples of Component.

       For example, how the injection in front of the SecondActivity Global instance of it? GlobalComponent can only rely on SecondComponent, it is understood to inherit.

       Look at the code!

@Singleton
@Component(modules = SecondModule.class,dependencies = GlobalComponent.class)
public interface SecondComponent {
    void inject(SecondActivity activity);
}

      Dependence can be used in parentheses, Here I would say that. I'm done.

      Careful might have found a blind monk Hua points. Yes, how they switched back to inject up? Is dependence on must inject way?

      First tribute to the students to observe very carefully.

      The answer is: no. I'm just too lazy to write code behind.

      How convenient to come back, in front of you in order to demonstrate it deliberately wrote about. Lazy people like me so naturally how simple how to.

      SecondActivity also changed, remember to compile, or monogram red.

public class SecondActivity extends AppCompatActivity {
    @BindView(R.id.second_text_1)    TextView text1;
    @BindView(R.id.second_text_2)    TextView text2;
    @BindView(R.id.second_text_3)    TextView text3;
    @BindView(R.id.second_text_4)    TextView text4;

    @Inject    Coffee coffee1;
    @Inject    Coffee coffee2;
    @Inject    Global global1;
    @Inject    Global global2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        ButterKnife.bind(this);

        DaggerSecondComponent.builder()
                .globalComponent(new MyApplication().get())
                .secondModule(new SecondModule())//添加Module
                .build()
                .inject(this);

        text1.setText(coffee1.toString());
        text2.setText(coffee2.toString());
        text3.setText(global1.toString());
        text4.setText(global2.toString());
    }
}

         The reference to the previous experimental group into a group, the experimental group into a reference group. (I went to junior high school biology science students should know.)

         Because it is bound SecondMoudle call secondMoudle, the inherited GlobalComponent, naturally have to call the input parameters is Component.

         Run about to discover, global injected into it.

 

 

         However, it is clear that not a single case. Because we do not have to deform it.

         Well, knock on the blackboard, do not bow to read, and all look at me, I want to start distorted.

         Talk about what points. @Scope can not directly use, we use before is a @Singleton default implementation, take a look at its source.

@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}

          We also own a set:

@Scope
@Documented
@Retention(RUNTIME)
public @interface MyScope {
}

         Very simple, right? Shining like a copy, it changed names.

         If love is that simple.

         Now is the hands-on time, replace SecondModule and SecondComponent in @Singleton into @MyScope, and then run it again to see if the result is not the same.

         I go to a toilet ......

         Run good students, go to GlobalModule and GlobalComponent in plus @Singleton. Pitted again.

         General classes are like, 30 minutes before the teacher, the students do exercises after fifteen minutes.

         I wrote some code, you have to practice.

         Let me guess, some naughty students, teachers taking advantage of the toilet did not come back on time, peeked behind the exercises, you want to be lazy.

         So very labor-saving, directly @MyScope added to the GlobalModule and GlobalComponent inside.

         Then on the error.

错误: This @Singleton component cannot depend on scoped components:
@com.yuanxixing.dagger2.MyScope com.yuanxixing.dagger2.GlobalComponent

         We must praise this group of students chose the road less traveled.

         Even if it is wrong, I just found a feasible method!

         Indeed, this is a hidden achievement.

         First talk about inheritance Component, which is Dependence.

         @Scope was a marked Component, when inheritance, it must also be @Scope Component mark. Here's why it should be, when inherited Component, it inherits the methods it provides, but we said before, is meant to Component mark @Scope there @Provide single case, it inherited a single case of Component also @Provde play on @Scope.

         @Scope and the two can not be the same. My approach is required in front of a @MyScope labeled SecondComponent to dependence is @Singleton marked GlobalComponent.

         But some students in turn tried, with @Singleton labeled SecondComponent to dependence is @MyScope marked GlobalComponent then on the error.

         I also tried a few cases, from @Scope tag definition Component inherit two, no problem.

         But @Singleton is not the same, it can only be labeled Component is dependence, it is superior, it can not be labeled Component does not need to rely on others.

         So, keep in mind on the line.

         Well, the last hard look at the teacher and then, write a test ThridActivity Global is not a global singleton.

public class ThridActivity extends AppCompatActivity {
    @BindView(R.id.thrid_text_1)    TextView text1;
    @BindView(R.id.thrid_text_2)    TextView text2;
    @BindView(R.id.thrid_text_3)    TextView text3;
    @BindView(R.id.thrid_text_4)    TextView text4;

    @Inject    Coffee coffee1;
    @Inject    Coffee coffee2;
    @Inject    Global global1;
    @Inject    Global global2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.thrid);
        ButterKnife.bind(this);

        DaggerSecondComponent.builder()
                .globalComponent(new MyApplication().get())
                .secondModule(new SecondModule())//添加Module
                .build()
                .inject(this);

        text1.setText(coffee1.toString());
        text2.setText(coffee2.toString());
        text3.setText(global1.toString());
        text4.setText(global2.toString());
    }
}

           layout code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thrid_text_1"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thrid_text_2"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thrid_text_3"
        />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thrid_text_4"
        />

</LinearLayout>

           See that I use to inject or DaggerSecondComponent, so I need to add the code in SecondComponent, adapting it ThrdActivity.

@MyScope
@Component(modules = SecondModule.class,dependencies = GlobalComponent.class)
public interface SecondComponent {
    void inject(SecondActivity activity);
    void inject(ThridActivity activity);
}

          Then add a click SecondActivity jump in, button their own to add.

    @OnClick({R.id.turn_thridactivity})
    public void onViewClicked(View view) {
        startActivity(new Intent(this, ThridActivity.class));
    }

           Then we can finish the look. . . . . .

           Oh shit! VM collapse.

          Well, your own Run!

          Next chapter repeat source.

Guess you like

Origin www.cnblogs.com/yuanxixing/p/11538001.html