我只尝试了1次,但进行了改造,但我遇到了错误 我想打电话给我的改造类,并给url和body类提供endPoint,并清楚地从服务器获取主体
ApiClient
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(App.SERVER)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
ApiService
public interface ApiService {
@POST("{urlEndPoint}")
<C, T> Call<C> request(@Body T body, @Path("urlEndPoint") String urlEndPoint);
}
改造对象
public class Request<C,T> {
private C c = null;
public C rest(T body, String urlEndPoint) {
ApiService apiService = ApiClient.getClient().create(ApiService.class);
Call<C> call = apiService.request(body, urlEndPoint);
call.enqueue(new Callback<C>() {
@Override
public void onResponse(Call<C> call, Response<C> response) {
if (response.isSuccessful())
c = response.body();
else
Toaster.shorter(App.context.getString(R.string.serverError));
@Override
public void onFailure(Call<C> call, Throwable t) {
Toaster.shorter(App.context.getString(R.string.connectionError));
}
});
return c;
}
}
调用方法:
private void requestForCode() {
Request request = new Request();
int i = (int) request.rest(App.car, "/Rest/ReturnActivationCode");
if (i == 0)
Toaster.longer(App.context.getString(R.string.validateYourNumber));
else
Toaster.shorter(App.context.getString(R.string.serverError));
}
错误:
12-05 12:18:04.119 773-907/? E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ id=535, legacyType=-1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]
12-05 12:18:09.575 10359-10359/com.rayanandisheh.peysepar E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.rayanandisheh.peysepar, PID: 10359
java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard: retrofit2.Call<C>
for method ApiService.request
at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:755)
at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:746)
at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:229)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:165)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:147)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.request(Unknown Source)
改造不支持通用对象???
答案 0 :(得分:0)
似乎您正在尝试通过调用泛型函数来最小化样板,但是有一种更好的方法可以做到这一点。
首先,您要用以下方法封装改造设置:
@POST("{urlEndPoint}")
<C, T> Call<C> request(@Body T body, @Path("urlEndPoint") String urlEndPoint);
然后使用创建的函数对其进行调用:
request.rest(App.object1, "endpoint");
但是实际上,这只会使事情变得复杂,并且代码紧密耦合。您仍然需要在每个不同的API(request.rest(App.object2, "endpoint2")
,request.rest(App.object3, "endpoint3")
)上调用相同的方法。这也限制了改造的能力(,例如多个参数,自定义标头等)。您可以做的只是按照改造步骤进行设置:
@POST("yourendpoint")
Call<YourObjectResp> saveObject(@Body YourObjectParam param)
为了尽量减少样板,建议将其设为功能:
Call<YourObjectResp> call = apiService.saveObject(new YourObjectParam());
call.enqueue(new ApiServiceOperator<>(new
ApiServiceOperator.OnResponseListener<YourObjectResp>() {
@Override
public void onSuccess(YourObjectResp body) {
// do something with your response object
}
@Override
public void onFailure(Throwable t) {
// here, you can create another java class to handle the exceptions
}
}));
针对您的ApiServiceOperator.java
:
/**
* Handles retrofit framework response.
* Extract the body if success, otherwise throw an exception.
*/
public class ApiServiceOperator<T> implements Callback<T> {
interface OnResponseListener<T> {
void onSuccess(T body);
void onFailure(Throwable t);
}
private OnResponseListener<T> onResponseListener;
public ApiServiceOperator(OnResponseListener<T> onResponseListener) {
this.onResponseListener = onResponseListener;
}
@Override
public void onResponse(@NonNull Call<T> call, @NonNull Response<T> response) {
if (response.isSuccessful()) { // here, do the extraction of body
onResponseListener.onSuccess(response.body());
} else {
onResponseListener.onFailure(new ServerErrorException());
}
}
@Override
public void onFailure(@NonNull Call<T> call, @NonNull Throwable t) {
onResponseListener.onFailure(new ConnectionErrorException());
}
// these exception can be on a separate classes.
public static class ServerErrorException extends Exception {
}
public static class ConnectionErrorException extends Exception {
}
}
通过这些设置,您仍然可以最大程度地减少样板操作,并且可以重复使用,可伸缩和可测试。 ApiServiceOperator
也与Android Context
松散耦合,而是引发一个普通的Java异常,您可以在其中创建一个知道Android Context
的函数,以基于引发的异常获取适当的消息。