lor*_*max 72 rest android web-services retrofit
我正在转向Retrofit并尝试理解使用异步回调的正确架构.
例如,我有一个界面:
interface RESTService{
@GET("/api/getusername")
void getUserName(@Query("user_id") String userId,
Callback<Response> callback);
}
Run Code Online (Sandbox Code Playgroud)
我从主要活动中运行这个:
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("WEBSITE_URL")
.build();
RESTService api = restAdapter.create(RESTService.class);
api.getUserName(userId, new Callback<Response> {...});
Run Code Online (Sandbox Code Playgroud)
然后用户旋转设备,我有新创建的活动......这里发生了什么?如何获得对新活动的响应(我假设api调用后台将比第一个活动生命执行更长时间).也许我必须使用静态回调实例或者什么?请告诉我正确的方法......
小智 42
使用otto.有很多样本要混合otto和改造,例如https://github.com/pat-dalberg/ImageNom/blob/master/src/com/dalberg/android/imagenom/async/FlickrClient.java
或者阅读这篇文章http://www.mdswanson.com/blog/2014/04/07/durable-android-rest-clients.html 它回答了几乎所有问题
小智 34
对于潜在的长时间运行的服务器调用,我使用AsyncTaskLoader.对我来说,Loaders的主要优点是活动 - 生命周期处理.仅当您的活动对用户可见时,才会调用onLoadFinished.活动/片段和方向更改之间也共享加载器.
所以,我创建了使用改造中同步调用的ApiLoader loadInBackground.
abstract public class ApiLoader<Type> extends AsyncTaskLoader<ApiResponse<Type>> {
protected ApiService service;
protected ApiResponse<Type> response;
public ApiLoader(Context context) {
super(context);
Vibes app = (Vibes) context.getApplicationContext();
service = app.getApiService();
}
@Override
public ApiResponse<Type> loadInBackground() {
ApiResponse<Type> localResponse = new ApiResponse<Type>();
try {
localResponse.setResult(callServerInBackground(service));
} catch(Exception e) {
localResponse.setError(e);
}
response = localResponse;
return response;
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if(response != null) {
deliverResult(response);
}
if(takeContentChanged() || response == null) {
forceLoad();
}
}
@Override
protected void onReset() {
super.onReset();
response = null;
}
abstract protected Type callServerInBackground(SecondLevelApiService api) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
在您的活动中,您可以像这样启动此加载器:
getSupportLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks<ApiResponse<DAO>>() {
@Override
public Loader<ApiResponse<DAO>> onCreateLoader(int id, Bundle args) {
spbProgress.setVisibility(View.VISIBLE);
return new ApiLoader<DAO>(getApplicationContext()) {
@Override
protected DAO callServerInBackground(ApiService api) throws Exception {
return api.requestDAO();
}
};
}
@Override
public void onLoadFinished(Loader<ApiResponse<DAO>> loader, ApiResponse<DAO> data) {
if (!data.hasError()) {
DAO dao = data.getResult();
//handle data
} else {
Exception error = data.getError();
//handle error
}
}
@Override
public void onLoaderReset(Loader<ApiResponse<DAO>> loader) {}
});
Run Code Online (Sandbox Code Playgroud)
如果要多次请求数据,请使用restartLoader而不是initLoader.
Leo*_*age 21
我一直在我的Android应用程序上使用一种MVP(ModelViewPresenter)实现.对于Retrofit请求,我使Activity调用它的各自的Presenter,它反过来生成Retrofit Request,并作为参数我发送一个附加了自定义Listener的Callback(由演示者实现).当Callback到达onSuccess或onFailure方法时,我调用Listener各自的方法,调用Presenter然后调用Activity方法:P
现在,如果屏幕被转动,当重新创建我的活动时,它会将自己附加到Presenter.这是使用Android应用程序的自定义实现进行的,它保留了演示者的实例,并使用地图根据Activity的类恢复正确的演示者.
我不知道如果这是最好的方式,也许@pareshgoel答案更好,但它一直在为我工作:D
public abstract interface RequestListener<T> {
void onSuccess(T response);
void onFailure(RetrofitError error);
}
Run Code Online (Sandbox Code Playgroud)
...
public class RequestCallback<T> implements Callback<T> {
protected RequestListener<T> listener;
public RequestCallback(RequestListener<T> listener){
this.listener = listener;
}
@Override
public void failure(RetrofitError arg0){
this.listener.onFailure(arg0);
}
@Override
public void success(T arg0, Response arg1){
this.listener.onSuccess(arg0);
}
}
Run Code Online (Sandbox Code Playgroud)
在演示者的某处实现侦听器,并在overrode方法上调用演示者的方法,该方法将调用Activity.并在演示者的任何地方打电话来启动所有内容:P
Request rsqt = restAdapter.create(Request.class);
rsqt.get(new RequestCallback<YourExpectedObject>(listener));
Run Code Online (Sandbox Code Playgroud)
希望它能帮到你.
par*_*oel 10
首先,您的活动在此处泄漏,因为此行:api.getUserName(userId,new Callback {...})创建一个匿名Callback类,该类包含对MainActivity的强引用.在调用Callback之前旋转设备时,MainActivity不会被垃圾回收.根据您在Callback.call()中执行的操作,您的应用可能会产生未定义的行为.
处理此类方案的一般想法是:
以上只是防止泄漏.它仍然无法帮助您将Retrofit回调给您的活动.
现在,即使在配置更改后,要将结果返回到组件(在您的情况下为Activity),您可能希望使用附加到Activity的无头保留片段,这会调用Retrofit.阅读更多关于保留片段的内容 - http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
一般的想法是Fragment自动将自身附加到Activity上的配置更改.
我强烈推荐你 观看Google I / O提供的该视频。
它讨论了如何通过将REST请求委托给服务来创建REST请求(该服务几乎从未被杀死)。请求完成后,它会立即存储到Android的内置数据库中,因此当您的“活动”准备就绪时,数据立即可用。
使用这种方法,您不必担心活动的生命周期,并且可以以更分离的方式处理您的请求。
该视频没有专门讨论改造,但是您可以轻松地将改造应用于此范例。
| 归档时间: |
|
| 查看次数: |
66227 次 |
| 最近记录: |