我目前正在创建Android应用并遇到问题,但我还没有解决。
我使用Retrofit库向服务器发送请求,根据Retrofit库在后台线程中完成。
我在主线程中调用此Retrofit请求,我想等待此后台线程完成以便处理其输出。
我在论坛上发现了类似的问题,但我不知道如何实施: Android: how to wait AsyncTask to finish in MainThread?
我用Retrofit调用请求,请求完成后,Callback对象的成功方法启动,但主线程仍在运行,它到达后台的最后一行任务已完成。
如何强制主线程等待后台任务完成?
我的代码:
// ... (main thread)
// CALL TO THE SERVER
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(LoginScreen.ENDPOINT).build();
WebServices getFiles = restAdapter.create(WebServices.class);
Callback<Response> callback = new Callback<Response>()
{
@Override
public void success(Response s, Response response)
{
fileAvailable = new String(((TypedByteArray) s.getBody()).getBytes());
//THIS IS EXECUTED WHEN THE BACKGROUND TASK IS FINISHED
}
@Override
public void failure(RetrofitError retrofitError)
{
Log.e(TAG, retrofitError.toString());
}
};
getFiles.getFiles(id, callback);
// I want here to work with fileAvailable, but the code
// reaches this line before the background task is over.
我尝试在上一个链接中创建一个Handler对象,并在success方法中调用sendEmptyMessage但它没有工作。
如果有人能帮助我,我将非常感激。
提前谢谢你,
答案 0 :(得分:3)
你不想阻止你的主线程,这就是这个库的重点。您需要重新考虑如何执行此操作,因为如果您阻止主线程,UI将挂起(无响应)并且用户将感到不安。想想你最后一次使用应用程序,所有内容都锁定了几秒钟。如果你阻止主线程就会发生这种情况。
相反,您应该在响应处理程序中继续您的逻辑,或者您可以从内部类调用外部类的函数(回调是内部类)。
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(LoginScreen.ENDPOINT).build();
WebServices getFiles = restAdapter.create(WebServices.class);
Callback<Response> callback = new Callback<Response>()
{
@Override
public void success(Response s, Response response)
{
fileAvailable = new String(((TypedByteArray) s.getBody()).getBytes());
doSomethingOnSuccess();
}
@Override
public void failure(RetrofitError retrofitError)
{
Log.e(TAG, retrofitError.toString());
}
};
//this runs before success(), so show a spinner or something,
//eg:http://stackoverflow.com/questions/9157504/put-a-progressbar-on-actionbar
}
- 更新(根据您对多个后台任务的评论 - 如果你有2个或更多的后台任务并行运行(意味着他们不依赖于彼此的输出),但你需要完成所有后续任务才能对它们做任何事情,它可能看起来像这样:
public class MyActivity extends Activity {
private Result result1 = null;
private Result result2 = null;
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
Callback<Response> callback1 = new Callback<Response>() {
@Override
public void success(Response s, Response response)
{
result1 = new String(((TypedByteArray) s.getBody()).getBytes());
checkComplete();
}
@Override
public void failure(RetrofitError retrofitError)
{
Log.e(TAG, retrofitError.toString());
}
};
Callback<Response> callback2 = new Callback<Response>() {
@Override
public void success(Response s, Response response)
{
result2 = new String(((TypedByteArray) s.getBody()).getBytes());
checkComplete();
}
@Override
public void failure(RetrofitError retrofitError)
{
Log.e(TAG, retrofitError.toString());
}
};
getFiles.getFiles(id, callback1);
otherthing.doSomething(id, callback2);
}
private void checkComplete() {
if (result1 != null && result2 != null) {
doSomethingWithResults();
}
}
private void doSomethingWithResults() {
//update UI
}
}
答案 1 :(得分:0)
主线程没有&#34;最后一行&#34; ,它正在进行中。 onCreate()
执行完毕后,主线程未完成。只需将要执行的代码放在成功处理程序中
//THIS IS EXECUTED WHEN THE BACKGROUND TASK IS FINISHED
是