【问题标题】:How to make a singleton for retrofit 2?如何为改造 2 制作单例?
【发布时间】:2017-01-16 08:46:45
【问题描述】:

如果存在多个retrofit调用,我该如何做一个retrofit的单例,这样类内就不会出现重复代码,从而摆脱不必要的代码。

【问题讨论】:

标签: android singleton gson retrofit


【解决方案1】:

这是一个例子,但是!尽管这可能很闪亮且易于使用,但单例是邪恶的。如果可能,尽量避免使用它们。一种解决方法是使用依赖注入。

无论如何。

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();

【讨论】:

  • 如你所说,他们是邪恶的。几周前我偶然发现了一个问题。当对不同的后端使用相同的 API 时(因此在运行时域会发生变化),那么单例不会从工厂创建新实例。使用类似的工厂模式解决了它。但是现在我周围有成千上万的 api 实例。有什么想法可以改进吗?
【解决方案2】:

要实现单例类,最简单的方法是将类的构造函数设为私有。

  1. 渴望初始化:

在Eager初始化中,Singleton Class的实例是在类加载时创建的,这是创建单例类最简单的方法。

public class SingletonClass {

private static volatile SingletonClass sSoleInstance = new SingletonClass();

    //private constructor.
    private SingletonClass(){}

    public static SingletonClass getInstance() {
        return sSoleInstance;
    }
}
  1. 延迟初始化:

此方法将检查是否已创建该类的任何实例?如果是,那么我们的方法 (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、线程安全和序列化安全 Singleton。

请查看此参考以获取更多详细信息和对单例对象创建的深入了解。

https://medium.com/@kevalpatel2106/digesting-singleton-design-pattern-in-java-5d434f4f322#.6gzisae2u

【讨论】:

    【解决方案3】:
    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;
    }
    

    【讨论】:

      【解决方案4】:
      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();
          }
      }
      

      【讨论】:

      【解决方案5】:

      我在 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)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 2019-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多