简体   繁体   English

Android:等待后台任务在主线程中完成

[英]Android : Wait for a background task to finish in main thread

I am currently creating an Android app and encounter an issue and I haven't solved yet. 我目前正在创建一个Android应用,遇到问题,但尚未解决。

I use the Retrofit library to send requests to a server, according to the Retrofit library it is done in a background thread. 根据Retrofit库,我使用Retrofit库将请求发送到服务器,这是在后台线程中完成的。

I call this Retrofit request in the main thread and I want to wait for this background thread to finish in order to work on its output. 我在主线程中调用此Retrofit请求,并且我想等待该后台线程完成以处理其输出。

I found a similar question on the forum but I don't know how to implement : Android: how to wait AsyncTask to finish in MainThread? 我在论坛上发现了类似的问题,但我不知道如何实现: Android:如何等待AsyncTask在MainThread中完成?

I call the request with Retrofit, when the request is finished, the success method of the Callback object starts , but main thread is still running and it reaches the last line before the background task has finished . 我用Retrofit调用请求, 当请求完成时,Callback对象的成功方法开始 ,但是主线程仍在运行,并且在后台任务完成之前到达最后一行

How can I force my main thread to wait for the background task to finish ? 如何强制我的主线程等待后台任务完成?

My code : 我的代码:

    // ... (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.

I tried to create a Handler object as in the previous link and call sendEmptyMessage in the success method but it didn't work. 我试图像前面的链接中那样创建一个Handler对象,并在成功方法中调用sendEmptyMessage,但是它不起作用。

I would be really grateful if somebody could help me. 如果有人可以帮助我,我将不胜感激。

Thank you in advance, 先感谢您,

You don't want to block your main thread, that's the whole point of this library. 您不想阻塞主线程,这就是该库的全部内容。 You need to reconsider how you do this because if you block the main thread the UI will hang (be unresponsive) and the user will be upset. 您需要重新考虑如何执行此操作,因为如果阻塞主线程,则UI会挂起(无响应),并且用户会感到不高兴。 Think about the last time you used an app and everything locked up for several seconds. 考虑一下您上一次使用应用程序时所有内容都锁定了几秒钟。 That is what happens if you block the main thread. 如果您阻塞主线程,则会发生这种情况。

Instead, you should continue your logic in the response handler, or you can call into a function of the outer class from the inner class (callback is the inner class). 相反,您应该在响应处理程序中继续执行逻辑,或者可以从内部类调用外部类的函数(回调是内部类)。

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

} }

-- Update (per your comment about having multiple background tasks -- If you've got 2 or more background tasks running in parallel (meaning they don't depend on each others output) but you need all of them to complete before you can do anything with them, it would probably look like this: -更新(根据您对具有多个后台任务的评论-如果您有两个或两个以上并行运行的后台任务(这意味着它们不依赖于彼此的输出),但是您需要先完成所有这些任务对他们做任何事情,可能看起来像这样:

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
  }

}

There's no "last line" for the main thread, it's ongoing. 主线程没有“最后一行” ,它正在进行中。 Main thread is not finished after onCreate() is done executing. onCreate()执行完成后,主线程未完成。 Just put the code you want to execute on the data into the success handler right where 只需将要对数据执行的代码放到成功处理程序中

//THIS IS EXECUTED WHEN THE BACKGROUND TASK IS FINISHED

is. 是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM