如果存在多个Retrofit调用,我该如何创建一个Retrofit的单例,以便在类中不会有重复的代码,并摆脱不必要的代码。
以下是一个例子,但是!虽然它可能看起来华丽且易于使用,但单例模式是有害的。如果可能的话,请尝试避免使用它们。解决这个问题的方法之一是使用依赖注入。
无论如何。
public class Api {
private static Api instance = null;
public static final String BASE_URL = "your_base_url";
// Keep your services here, build them in buildRetrofit method later
private UserService userService;
public static Api getInstance() {
if (instance == null) {
instance = new Api();
}
return instance;
}
// Build retrofit once when creating a single instance
private Api() {
// Implement a method to build your retrofit
buildRetrofit(BASE_URL);
}
private void buildRetrofit() {
Retrofit retrofit = ...
// Build your services once
this.userService = retrofit.create(UserService.class);
...
}
public UserService getUserService() {
return this.userService;
}
...
}
UserService userService = Api.getInstance().getUserService();
实现单例模式最简单的方法是将类的构造函数设为私有。
在饱汉式中,单例类的实例在类加载时创建,这是创建单例类的最简单方法。
public class SingletonClass {
private static volatile SingletonClass sSoleInstance = new SingletonClass();
//private constructor.
private SingletonClass(){}
public static SingletonClass getInstance() {
return sSoleInstance;
}
}
该方法会检查该类的实例是否已经被创建?如果是,则我们的方法(getInstance())将返回旧实例,否则它将在JVM中创建单例类的新实例并返回该实例。这种方法被称为懒加载。
public class SingletonClass {
private static SingletonClass sSoleInstance;
private SingletonClass(){} //private constructor.
public static SingletonClass getInstance(){
if (sSoleInstance == null){ //if there is no instance available... create new one
sSoleInstance = new SingletonClass();
}
return sSoleInstance;
}
}
除了Java反射API、线程安全和序列化安全单例模式外,还有其他一些内容。
请参考此引用以获取更多详细信息和深入理解单例对象创建。
https://medium.com/@kevalpatel2106/digesting-singleton-design-pattern-in-java-5d434f4f322
public class Singleton {
private static Singleton INSTANCE = null;
// other instance variables can be here
private Singleton() {};
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return(INSTANCE);
}
// other instance methods can follow
}
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
@Module
public class NetworkModule {
@Provides
@Singleton
public Gson gson() {
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create();
}
@Provides
@Singleton
public HttpLoggingInterceptor loggingInterceptor() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(
message -> Timber.i(message));
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return interceptor;
}
@Provides
@Singleton
public Cache cache(File cacheFile) {
return new Cache(cacheFile, 10 * 1000 * 1000); //10MB Cache
}
@Provides
@Singleton
public File cacheFile(@ApplicationContext Context context) {
return new File(context.getCacheDir(), "okhttp_cache");
}
@Provides
@Singleton
public OkHttpClient okHttpClient(HttpLoggingInterceptor loggingInterceptor, Cache cache) {
return new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.cache(cache)
.build();
}
@Provides
@Singleton
public Retrofit retrofit(OkHttpClient okHttpClient, Gson gson) {
return new Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okHttpClient)
.baseUrl("you/base/url")
.build();
}
}
public class Singleton {
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
我已经在 Kotlin 中尝试过:
class RetrofitClient{
companion object
{
var retrofit:Retrofit?=null;
fun getRetrofitObject():Retrofit?
{
if(retrofit==null)
{
synchronized(RetrofitClient ::class.java)
{
retrofit=Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("YOUR_BASE_URL")
.build()
}
}
return retrofit
}
}
}
然后:
var service: ServicesInterface? = RetrofitClient.getRetrofitObject()?.create(ServicesInterface::class.java)