java - Android:通用改造 2
问题描述
我只尝试了 1 次创建改造但我有错误我想调用我的改造类并给出 url 和正文类的端点,并清楚地从服务器获取正文
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)
改造不支持通用对象???
解决方案
您似乎正在尝试通过调用通用函数来最小化样板文件,但是有更好的方法可以做到这一点。
首先,您将使用以下内容封装改造设置:
@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
根据抛出的异常获取适当的消息。
推荐阅读
- html - Flexbox 列垂直间距 - 之间不起作用
- r - 对按另一个因子分组的因子的每个级别进行计数
- c# - 使用 ModelState 验证 DTO
- java - 在 Netty 服务器中未调用 RequestHandler
- gtk3 - 如何使用 GTK 将按键事件发送到非活动条目
- json - 在 Python 3 中从 Google API JSON 中提取几何/位置键:AttributeError: 'list' object has no attribute 'read'
- python - 如何在python中解析requests.session cookie属性
- pandas - 如何按日期列的月和日部分分组,以便一年获得 365 个组
- react-native - 如何在标题中有自定义导航
- apache-camel - concurrentConsumers 值是否会影响 Camel 处理器线程的数量?