美文网首页
Dagger 作用域Singleton

Dagger 作用域Singleton

作者: coke613 | 来源:发表于2023-07-17 09:59 被阅读0次

    先看代码

    public  interface Api {
        @POST("/api/sdk/v1/init")
        Call<String> login();
    }
    
    

    // 声明Module

    @Module
    public class NetWorkModule {
        @Provides
        public Retrofit provideRetrofit(){
            return new Retrofit.Builder()
                    .baseUrl("https://www.google.com")
                    .build();
        }
    
    
        @Provides
        public Api providesApi(Retrofit retrofit){
            return retrofit.create(Api.class);
        }
    
    }
    

    // 将Module 装到Component 容器中

    @Component(modules = NetWorkModule.class)
    public interface ApplicationCommponent {
        void inject(TextDaggerActivity mainActivity);
    }
    
    public class TextDaggerActivity extends AppCompatActivity {
    
    
       @Inject
       Retrofit retrofit1;
    
       @Inject
       Retrofit retrofit2;
    
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
    
          DaggerApplicationCommponent.create(). inject(this);
    
          Log.e("retrofit1----","address: "+retrofit1);
          Log.e("retrofit2----","address: "+retrofit2);
       }
    }
    
     打印结果:
    E/retrofit1----: address: retrofit2.Retrofit@5707fc6
    E/retrofit2----: address: retrofit2.Retrofit@f8eb87
    

    在项目开发中, Retrofit 应该是全局的,单一的.
    那如何修改呢?

    修改 NetWorkModule , 在具备单一性的函数上添加 @Singleton 注解.

    @Module
    public class NetWorkModule {
        @Provides
        @Singleton
        public Retrofit provideRetrofit(){
            return new Retrofit.Builder()
                    .baseUrl("https://www.google.com")
                    .build();
        }  
        @Singleton  
        @Provides
        public Api providesApi(Retrofit retrofit){
            return retrofit.create(Api.class);
        }
    
    }
    
    

    同时,在Component 容器上也要添加 @Singleton 注解.

    
    @Singleton
    @Component(modules = NetWorkModule.class)
    public interface ApplicationCommponent {
        void inject(TextDaggerActivity mainActivity);
    
    }
    
    

    此时,再次运行代码.

    打印结果: 
    E/retrofit1----: address: retrofit2.Retrofit@5707fc6
    E/retrofit2----: address: retrofit2.Retrofit@5707fc6
    

    如此,看样子确实是实现了单例模式.

    创建TextDaggerActivity2.class. 同时修改ApplicationCommponent.

    @Singleton
    @Component(modules = NetWorkModule.class)
    public interface ApplicationCommponent {
        void inject(TextDaggerActivity mainActivity);
        void inject(TextDaggerActivity2 mainActivity);
    
    }
    
    public class TextDaggerActivity extends AppCompatActivity {
        ...
        @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
            ...
    
           startActivity(new Intent(this,TextDaggerActivity2.class));
       }
     
    }
    
    public class TextDaggerActivity2 extends AppCompatActivity {
    
       @Inject
       Retrofit retrofit;
    
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          DaggerApplicationCommponent.create(). inject(this);
          Log.e("retrofit3----","address: "+retrofit);
       }
    }
    
    

    两个Activity 都声明了Retrofit, 并使用@Inject 注入. 看一下执行结果

    打印结果: 
    E/retrofit1----: address: retrofit2.Retrofit@5707fc6
    E/retrofit2----: address: retrofit2.Retrofit@5707fc6
    E/retrofit3----: address: retrofit2.Retrofit@48b72b9
    

    可见Dagger 中的@Singleton注解并不是真正意义上的单例模式。而是局部单例模式.

    在Dagger 中,@Singleton注解用于标记一个对象的作用域范围,表示在同一个作用域内只会创建一个对象实例,但它不能保证对象的唯一性.

    拿到代码上来说, 被@Singleton 修饰的容器,它们的作用域一个在TextDaggerActivity, 另一个在TextDaggerActivity2 进行create(), 两个是不同的作用域的,所以也就导致了局部单例.

    如何实现真正意义上的单例呢?
    自定义Application, 被@Singleton 修饰的容器作用域指定为全局.

    public class App extends Application {
    
       public static ApplicationCommponent applicationCommponent;
    
       @Override
       public void onCreate() {
          super.onCreate();
          applicationCommponent = DaggerApplicationCommponent.create();
       }
    }
    
    
    // TextDaggerActivity  & TextDaggerActivity2 修改为:
    App.applicationCommponent.injectUser(this);
    
    

    此时,再次运行代码.

    打印结果: 
    E/retrofit1----: address: retrofit2.Retrofit@5707fc6
    E/retrofit2----: address: retrofit2.Retrofit@5707fc6
    E/retrofit3----: address: retrofit2.Retrofit@5707fc6
    

    总结 :

    Dagger中的@Singleton注解并不是真正意义上的单例模式。在Dagger中,@Singleton注解用于标记一个对象的作用域范围,表示在同一个作用域内只会创建一个对象实例,但它并不能保证这个对象的唯一性.

    相关文章

      网友评论

          本文标题:Dagger 作用域Singleton

          本文链接:https://www.haomeiwen.com/subject/dxrwudtx.html