Ben*_*hee 4 android-syncadapter retrofit2
我通过SyncAdapter onPerformSync发送几个改装调用,我试图通过try/catch sleep语句发送来调节http调用.但是,这会阻止UI,并且只有在完成所有调用后才会响应.
什么是在onPerformSync中在后台调节网络调用(使用睡眠定时器)而不阻止UI的更好方法?
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
String baseUrl = BuildConfig.API_BASE_URL;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(HTTPService.class);
Call<RetroFitModel> RetroFitModelCall = service.getRetroFit(apiKey, sortOrder);
RetroFitModelCall.enqueue(new Callback<RetroFitModel>() {
@Override
public void onResponse(Response<RetroFitModel> response) {
if (!response.isSuccess()) {
} else {
List<RetroFitResult> retrofitResultList = response.body().getResults();
Utility.storeList(getContext(), retrofitResultList);
for (final RetroFitResult result : retrofitResultList) {
RetroFitReview(result.getId(), service);
try {
// Sleep for SLEEP_TIME before running RetroFitReports & RetroFitTime
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
}
RetroFitReports(result.getId(), service);
RetroFitTime(result.getId(), service);
}
}
}
@Override
public void onFailure(Throwable t) {
Log.e(LOG_TAG, "Error: " + t.getMessage());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
"onPerformSync"代码在"SyncAdapterThread"线程内执行,而不是在主UI线程内执行.但是,在使用回调进行异步调用时,这可能会发生变化(这是我们的情况).
在这里,您正在使用Retrofit"call.enqueue"方法的异步调用,这会对线程执行产生影响.我们现在需要提出的问题是:
回调方法将在何处执行?
为了得到这个问题的答案,我们必须确定将发布回调的Handler将使用哪个Looper.
如果我们自己玩处理程序,我们可以定义looper,处理程序以及如何处理处理程序之间的消息/ runnables.但这次是不同的,因为我们正在使用第三方框架(Retrofit).所以我们必须知道Retrofit使用哪个looper?
请注意,如果Retrofit尚未定义他的looper,你可能会遇到一个异常,说你需要一个looper来处理回调.换句话说,异步调用需要在looper线程中,以便将回调发送回执行它的线程.
根据Retrofit(Platform.java)的代码源:
static class Android extends Platform {
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor == null) {
callbackExecutor = new MainThreadExecutor();
}
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以注意到"Looper.getMainLooper()",这意味着Retrofit会将消息/ runnables发布到主线程消息队列中(您可以对此进行研究以获得进一步的详细说明).因此,发布的消息/ runnable将由主线程处理.
所以说,onResponse/onFailure回调将在主线程中执行.如果你做了太多的工作(Thread.sleep(SLEEP_TIME);),它会阻止UI.您可以自己检查:只需在"onResponse"回调中创建一个断点并检查它正在运行的线程.
那么如何处理这种情况呢?(关于改造使用的问题的答案)
由于我们已经在后台线程(SyncAdapterThread)中,因此不需要在您的情况下进行异步调用.只需进行Retrofit同步调用,然后处理结果,或记录失败.这样,您就不会阻止UI.
| 归档时间: |
|
| 查看次数: |
1397 次 |
| 最近记录: |