您的足迹:首页 > Android >Android Dagger2 笔记3 Scope作用域

Android Dagger2 笔记3 Scope作用域

上篇笔记1 讲到了单例@Singleton ,其实这个 @Singleton 是一个scope,@Singleton可以保证在同一个Component中,一个对象是单例对象。其实可以跟进去看Singleton源码:

@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
代码就这么多,其实就是一个作用域,或者叫自定义的生命周期,这个生命周期与Component相关。之所以起个名字叫singleton是为了方便辨认用此名称注解的是为了用到单例功能。所以我们也可以自定义scope来满足我们的需求。比如自定义一个ActivityScope,来替换上面的@singleton,看看是否达到在同一个component里实现单例:
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {}
然后把@Singleton全部替换为@ActivityScope:
@ActivityScope
public class UserInfo {

    @Inject
    public UserInfo(){
        AWLogUtils.e(" --- UserInfo created:" +this);
    }
}
@Module
public class LoginModule {

    Context context;

    public LoginModule(Context context){
        this.context=context;
    }

    @Provides
    Context provideContext(){
        AWLogUtils.e("--- provideContext---");
        return this.context;
    }

    @ActivityScope
    @Provides
    LocationInfo provideLocationInfo(Context context){
        LocationInfo locationInfo=new LocationInfo(context);
        AWLogUtils.e("--- provideLocationInfo---:"+locationInfo);
        return locationInfo;
    }

}
@ActivityScope
@Component(modules = {LoginModule.class})
public interface LoginComponent {
    void inject(LoginActivity loginActivity);
}
public class LoginActivity extends AppCompatActivity {
    @Inject
    UserInfo userInfo;

    @Inject
    UserInfo userInfo2;

    @Inject
    LocationInfo locationInfo;

    @Inject
    LocationInfo locationInfo2;

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


        DaggerLoginComponent.builder().loginModule(new LoginModule(getApplicationContext())).build().inject(this);

        AWLogUtils.e(" userInfo:"+userInfo);
        AWLogUtils.e(" userInfo2:"+userInfo2);
        AWLogUtils.e(" locationInfo:"+locationInfo);
        AWLogUtils.e(" locationInfo2:"+locationInfo2);
    }
}
运行结果:
02-27 09:25:54.488 E/AWLogUtils:  --- UserInfo created:com.a1anwang.chihuo.entity.UserInfo@78785cf
02-27 09:25:54.489 E/AWLogUtils: --- provideContext---
02-27 09:25:54.489 E/AWLogUtils:  ---create LocationInfo:com.a1anwang.chihuo.entity.LocationInfo@c933b5c
02-27 09:25:54.489 E/AWLogUtils: --- provideLocationInfo---:com.a1anwang.chihuo.entity.LocationInfo@c933b5c
02-27 09:25:54.490 E/AWLogUtils:  userInfo:com.a1anwang.chihuo.entity.UserInfo@78785cf
02-27 09:25:54.490 E/AWLogUtils:  userInfo2:com.a1anwang.chihuo.entity.UserInfo@78785cf
02-27 09:25:54.490 E/AWLogUtils:  locationInfo:com.a1anwang.chihuo.entity.LocationInfo@c933b5c
02-27 09:25:54.490 E/AWLogUtils:  locationInfo2:com.a1anwang.chihuo.entity.LocationInfo@c933b5c
可以看到,和之前的singleton运行效果是一样的。 那么,如果我想实现全局单例怎么办?上面说了,Scope或者叫自定义的生命周期,这个生命周期与Component相关,如果有一个全局的Component不就行了吗?那么AppComponent可以达到这个要求。
@Singleton
public class UserInfo {
    @Inject
    public UserInfo(){
        AWLogUtils.e(" --- UserInfo created:" +this);
    }
}
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    void inject(App app);

    // 向下层提供Context
    Context getContext();
    UserInfo getUserInfo();//这句话一定要加,很容易疏漏,不加报错
}
@Module
public class AppModule {

    Context context;

    public AppModule(Context context){
        this.context=context;
    }

    @Provides
    Context provideContext(){
        AWLogUtils.e("--- provideContext---");
        return this.context;
    }
}
public class App extends Application {

    AppComponent appComponent;

    @Inject
    UserInfo userInfo0;

    @Override
    public void onCreate() {
        super.onCreate();
        appComponent=DaggerAppComponent.builder().appModule(new AppModule(this)).build();
        appComponent.inject(this);//这句话保证注入userInfo0
        AWLogUtils.e(" userInfo0:"+userInfo0);
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }
}
@ActivityScope
@Component(modules = {LoginModule.class},dependencies = {AppComponent.class})
public interface LoginComponent {
    void inject(LoginActivity loginActivity);
}
public class LoginActivity extends AppCompatActivity {
    @Inject
    UserInfo userInfo1;

    @Inject
    UserInfo userInfo2;

    @Inject
    LocationInfo locationInfo1;

    @Inject
    LocationInfo locationInfo2;

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

        App app= (App) getApplication();

        DaggerLoginComponent.builder().appComponent(app.getAppComponent()).loginModule(new LoginModule()).build().inject(this);

        AWLogUtils.e(" userInfo1:"+userInfo1);
        AWLogUtils.e(" userInfo2:"+userInfo2);
        AWLogUtils.e(" locationInfo1:"+locationInfo1);
        AWLogUtils.e(" locationInfo2:"+locationInfo2);
        findViewById(R.id.btn_next).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(LoginActivity.this,RegisterActivity.class));
            }
        });
    }
}
@ActivityScope
@Component(dependencies = {AppComponent.class})
public interface RegisterComponent {
    void inject(RegisterActivity registerActivity);
}
public class RegisterActivity extends AppCompatActivity {
    @Inject
    UserInfo userInfo3;

    @Inject
    UserInfo userInfo4;


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

        App app= (App) getApplication();

        DaggerRegisterComponent.builder().appComponent(app.getAppComponent()).build().inject(this);

        AWLogUtils.e(" userInfo3:"+userInfo3);
        AWLogUtils.e(" userInfo4:"+userInfo4);

    }
}

运行结果:
02-28 12:42:58.007 E/AWLogUtils:  --- UserInfo created:com.a1anwang.chihuo.entity.UserInfo@96760bd
02-28 12:42:58.009 E/AWLogUtils:  userInfo0:com.a1anwang.chihuo.entity.UserInfo@96760bd
02-28 12:42:58.079 E/AWLogUtils: --- provideContext---
02-28 12:42:58.080 E/AWLogUtils:  ---create LocationInfo:com.a1anwang.chihuo.entity.LocationInfo@84597e0
02-28 12:42:58.080 E/AWLogUtils: --- provideLocationInfo---:com.a1anwang.chihuo.entity.LocationInfo@84597e0
02-28 12:42:58.080 E/AWLogUtils:  userInfo1:com.a1anwang.chihuo.entity.UserInfo@96760bd
02-28 12:42:58.080 E/AWLogUtils:  userInfo2:com.a1anwang.chihuo.entity.UserInfo@96760bd
02-28 12:42:58.080 E/AWLogUtils:  locationInfo1:com.a1anwang.chihuo.entity.LocationInfo@84597e0
02-28 12:42:58.080 E/AWLogUtils:  locationInfo2:com.a1anwang.chihuo.entity.LocationInfo@84597e0
02-28 12:43:01.112 E/AWLogUtils:  userInfo3:com.a1anwang.chihuo.entity.UserInfo@96760bd
02-28 12:43:01.112 E/AWLogUtils:  userInfo4:com.a1anwang.chihuo.entity.UserInfo@96760bd
可以看出UserInfo是全局单例了。这里面最容易出错的地方是 AppComponent 里面忘记加:
UserInfo getUserInfo();//这句话一定要加,很容易疏漏,不加报错
本博客所有文章如无特别注明均为原创。作者:AlanWang复制或转载请以超链接形式注明转自 AlanWang的博客-专注android和蓝牙BLE技术分享
原文地址《Android Dagger2 笔记3 Scope作用域

相关推荐

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交

网友评论(0)