2016-04-30 65 views
4

我正在使用Retrofit与我的REST API进行交互,并且想知道是否有人有任何设计建议。Android Retrofit设计模式

我的应用程序有以下软件包:

  1. 车型
  2. 服务
  3. 活动
  4. 片段

服务包中包含用于改造的接口。例如:

public interface FooService { 
    @FormUrlEncoded 
    @POST("foo/do") 
    @Headers("Content-Type: application/x-www-form-urlencoded; charset=UTF-8") 
    Call<FooBar> do(); 
} 

模型包含...以及不同的模型。例如,FooBar。目前为止这么好 - 就像每个Retrofit文档一样。

我已经创建了一个API类,即处理改造构建逻辑(Retrofit retrofit = new Retrofit.Builder()等),并公开静态字段:retrofit.In我的活动我则可以执行我的要求如下:

FooService service = API.retrofit.create(FooService.class); 
Call<FooBar> call = service.do(); 

try { 
    retrofit2.Response response = call.execute(); 
    // ...do stuff... 
} catch(IOException) {} 

而且随即出现我的问题:将上述内容进一步抽象出来会更好吗?这样我就不需要在上面重复以上了?例如,类似的东西:

MyOtherFooService service = new MyOtherFooService(); 
FooBar fooBar = service.do(); 

有什么想法?建议?

回答

9

我通常使用模式与结构如下:

首先定义ServiceHelper类似以下内容:

public class ServiceHelper { 

private static final String ENDPOINT = "http://test.com"; 

private static OkHttpClient httpClient = new OkHttpClient(); 
private static ServiceHelper instance = new ServiceHelper(); 
private IPlusService service; 


private ServiceHelper() { 

    Retrofit retrofit = createAdapter().build(); 
    service = retrofit.create(IPlusService.class); 
} 

public static ServiceHelper getInstance() { 
    return instance; 
} 

private Retrofit.Builder createAdapter() { 

    httpClient.setReadTimeout(60, TimeUnit.SECONDS); 
    httpClient.setConnectTimeout(60, TimeUnit.SECONDS); 
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
    httpClient.interceptors().add(interceptor); 

    return new Retrofit.Builder() 
      .baseUrl(ENDPOINT) 
      .client(httpClient) 
      .addConverterFactory(GsonConverterFactory.create()); 
} 

public Call<List<CategoryModel>> getAllCategory() { 
    return service.getAllCategory(); 
} 

然后把所有的服务于IService(在我的情况下,它IPlusService

public interface IPlusService { 
    //@Headers("Content-Type: application/json") in Post method may use this 
    @GET("/api/category") 
    Call<List<CategoryModel>> getAllCategory(); 
} 

然后拨打你的唱歌leton像你的活动/片段下面:

ServiceHelper.getInstance().getAllCategory().enqueue(new Callback<List<CategoryModel>>() { 
     @Override 
     public void onResponse(Response<List<CategoryModel>> response, Retrofit retrofit) { 
      processResponse(response); 
     } 

     @Override 
     public void onFailure(Throwable t) { 
      processResponse(null); 
     } 
    }); 
+0

这段代码取自我以前的项目,它使用改进版本:'retrofit:2.0.0-beta2',我认为你应该改变一下。 – Amir

+0

这是我的方法以及埃米尔,如改造书中所述。 https://leanpub.com/retrofit-love-working-with-apis-on-android。我喜欢你没有添加任何东西的事实。 KISS :) – Radu

+0

@Radu真的吗? :D我从2年前开始使用这种方法。我从我的一位同事那里学到了这一点。 BTW感谢您的伟大的方法;) – Amir

1

我会说不这样做。特别是因为大多数调用都需要使用异步.enqueue并以不同的方式处理错误响应。

您可以制作自己的抽象Retrofit回调类,并从中抽象出“自定义”回调,这样可以节省自己的代码重复。

但通常我希望看到应用程序逻辑在发出请求的同一个地方处理响应。

不要陷入过度使用它的陷阱,或者应用一些不适合Android的滥用模式。

如果你真的需要从活动/片段中传递响应,只需使用RxJava甚至LocalBroadcast。另请尝试阅读Retrofit书。

+0

你的意思是你在书中使用的方法不好? – Amir

+1

@Amir这本书很棒。我建议大家购买它。尽管这本书的内容可以在博客中免费阅读,但这本书是最好的选择。我建议那个问这个问题的人,他不是以一种模式开始的。相反,他应该使用常识,并在他的活动/片段中使用异步调用。当结果需要广播时,我使用LocalBroadcast或RxJ – Radu

+0

感谢Radu,Amir。在一个有点相关的说明:你会推荐为这里使用的所有异步任务创建一个单独的包吗?或者把它们保持为内部类? – JB2