先看代码
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注解用于标记一个对象的作用域范围,表示在同一个作用域内只会创建一个对象实例,但它并不能保证这个对象的唯一性.
网友评论