使用Retrofit2(多种服务)的最佳实践

时间:2018-12-03 14:41:10

标签: android kotlin retrofit2

我正在使用Kotlin编写Android应用,并集成了Retrofit2。

据我了解(如果我错了,请纠正我),这样做的“传统”方式是:

  1. 创建一个接口,其中包括我所有API的方法定义。
  2. 使用Retrofit.create()将其传递到改造中,该改造过程将为我实现,然后我就可以使用步骤#1中的功能来访问所有这些子

看过this之后,我的问题是: 为我的每个请求创建一个单独的界面是更好的做法吗?

例如如果我有一个“ LoginRequest”,并按如下所示实现(“ create”本质上调用Retrofit.create()),则下次我要添加/删除API时,只需添加/删除1个文件,而不是几个地方(请求本身,步骤1的服务以及使用步骤2的方法的所有地方)。另一方面,这将导致我的应用“知道”改造2,而且我不确定这是否是一种好习惯。

interface MyRequest {
    fun execute()
}

class LoginRequest (private val email: String, private val password: String) : MyRequest {
    interface LoginRequestService {
        @POST("login")
        fun emailLogin(
                @Body loginRequestBody: LoginRequestBody):
                retrofit2.Call<GetUserDetailsResponse>
    }

    override fun execute() {
        val requestBody = LoginRequestBody(email, password)
        val call = MyRequestManager.create(LoginRequestService::class.java).emailLogin(requestBody)
        MyRequestManager.executeCall(call)
    }
}

2 个答案:

答案 0 :(得分:2)

如果您遵循官方指南https://square.github.io/retrofit/

,那就更好了。
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}


Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();



GitHubService service = retrofit.create(GitHubService.class);

Call<List<Repo>> repos = service.listRepos("octocat");

那么您可以更轻松地获得一个Singleton服务,我还希望为每个调用创建接口,例如波纹管,它将在我想要的任何类中使用。

interface IListRepos {
    fun listRepos(user: String, onResponse: (MutableList<Repo>?) -> Unit) {
        ServiceSingleton.client.create(GitHubService::class.java)
                .listRepos(user)
                .enqueue(object : Callback<MutableList<Repo>> {
                    override fun onResponse(call: Call<MutableList<Repo>>,
                                            response: retrofit2.Response<MutableList<Repo>>) {
                        onResponse(response.body())
                    }

                    override fun onFailure(call: Call<MutableList<Repo>>, t: Throwable) {
                        onResponse(null)
                    }
                })
    }
}

答案 1 :(得分:1)

即时通讯在Java中的执行方式 对所有人都有1个接口,并带有单独的请求。

内部

public interface ApiInterface {
}

我将所有网址设置在一个位置,以便以后在

上进行轻松编辑
String Base_Url = "http://url.com/store/web/app_dev.php/api/";
String Base_Url_Channel = "http://url.com/store/web/app_dev.php/api/APP_STORE/";
String Image_URL_Online = "http://url.com/store/web/media/image/";

retrofit2方法调用类

public class DataServiceGenerator {

    public static <S> S createService(Class<S> serviceClass) {

        String url = ApiInterface.Base_Url;
        Retrofit.Builder builder = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(url);

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
                .readTimeout(15, TimeUnit.SECONDS)
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(25, TimeUnit.SECONDS);

        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
                    .setLevel(HttpLoggingInterceptor.Level.BODY);
            httpClient.addInterceptor(interceptor);
            httpClient.addNetworkInterceptor(new StethoInterceptor()); // for debugging
        }
        builder.client(httpClient.build());
        Retrofit retrofit = builder.build();
        return retrofit.create(serviceClass);
    }
 }

现在可以在界面中使用以下方法调用API即时通讯

@Multipart
@Headers("Accept: Application/json")
@POST("oauth/v2/token")
Call<Token_Model> token(
        @Part("client_id") RequestBody id,
        @Part("client_secret") RequestBody secret,
        @Part("grant_type") RequestBody username,
        @Part("username") RequestBody name,
        @Part("password") RequestBody password);

对于方法本身:

Call<Token_Model> call = service.token(createPartFromString("13123khkjhfsdf"),
                createPartFromString("1asd234k234lkh24"),
                createPartFromString("password"), createPartFromString("api@example.com"), createPartFromString("test"));
        call.enqueue(new Callback<Token_Model>() {
            @Override
            public void onResponse(Call<Token_Model> call, retrofit2.Response<Token_Model> response) {
                if (response.isSuccessful()) {
                    token_model = response.body();
                    if (token_model != null) {
                        helper.setToken(token_model.getAccess_token());
                    }

                } else {
                    Toast.makeText(context, context.getString(R.string.failed_token), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<Token_Model> call, Throwable t) {
                Toast.makeText(context, context.getString(R.string.failed_token), Toast.LENGTH_LONG).show();
            }
        });