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

时间:2015-09-03 16:12:16

标签: java android multithreading android-asynctask

我目前正在创建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但它没有工作。

如果有人能帮助我,我将非常感激。

提前谢谢你,

2 个答案:

答案 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