【问题标题】:how to allow UI thread to wait for the background thread to finish?如何让 UI 线程等待后台线程完成?
【发布时间】:2017-05-15 10:46:27
【问题描述】:

我可以使用 AsnycTask get() 方法等待后台任务完成,但是如果我使用 CursorLoader 和 ContentProvider 和 LoaderManager 回调,我该怎么做呢?

是否也可以防止UI线程等待后台线程返回数据?

【问题讨论】:

  • Loader 的整体理念是,在您获得数据之前,您不会让 UI 线程等待、显示空屏幕、虚拟数据或加载微调器
  • 是的,否则如果您想使用内容解析器,您需要将流程包装在 AsyncTask 中。

标签: android multithreading loader


【解决方案1】:

您可以轻松地通过您的界面来获取 Asynctask 的回调。这是解决问题的正确方法

【讨论】:

  • AsyncTask 的整个想法是提供一种进出主线程的方法。我不知道你为什么要使用回调接口。
【解决方案2】:

显示 ProgressDialog 以等待未收到响应。如果您的响应是从同一类或活动接收的,则不要使用接口回调,如果响应是从类的其他活动接收的,则使用接口回调

【讨论】:

    【解决方案3】:

    不建议等待 UIThread,它会使应用看起来迟钝或卡住。 blundell 在编辑中提出了很好的观点。

    【讨论】:

      【解决方案4】:

      在我当前的一个项目中,我遇到了完全相同的情况,我必须使用内容提供程序和光标加载器请求联系人列表,以便稍后在列表视图中显示它们。

      所以这是你应该做的:

      • 使用异步任务作为静态内部类,从您的活动/片段中对内容提供者进行异步调用。
      • 在 AsyncTask doInBackground() 方法中放置函数以检索光标并在那里处理数据,因此最终返回 List<Object> 在我的例子中,对象是返回的模型(联系人)。
      • 在 AsyncTask 的 onPostExecute() 方法中,您只需将检索到的数据列表传递给您正在使用的任何视图(在我的情况下,它还是一个 List<Contact>,您的 mainThread 在那里接收数据,只有在那里它必须处理准备好后的数据。

      AsyncTask 让您的生活更轻松,因为它们具有字符串结构来处理将数据从 MainThread 传递到后台单独线程,然后将数据从后台 Thread 发送回 MainThread。

      就代码而言,您的代码应如下所示:

      public class MainActivity extends Activity {
          private AsyncTask mTask;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              //
              ...... 
              //Call the AsyncTask and pass your Data
              mTask = new Task(this);
              mTask.execute();
          }
      
          private static class Task extends AsyncTask<Void, Void, List<Object> {
              private WeakReference<Contex> mContextRef;
              public Task(Context context) {
                  mContextRef = new WeakReference<>(context);
                  //later when you need your context just use the 'get()' method. like : mContextRef.get() (this will return a Context Object.
              }
      
              @Override
              protected void onPreExecute() {
                  // show progress Dialog
                 //this method is processed in the MainThread, though it can prepare data from the background thread.
              }
      
              @Override
              protected List<Object> doInBackground(Void ... params) {
                  List<Object> mList = new ArrayList<>();
                  //Call your content provider here and gather the cursor and process your data..
                 //return the list of object your want to show on the MainThread.
                 return mList;
              }
      
              @Override
              protected Void onPostExecute(List<Object> list) {
                  if(list.size() > 0) {
                  //do your stuff : i.e populate a listView
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        • 2012-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多