如何让UI线程等待后台线程完成?

时间:2016-12-31 11:41:43

标签: android multithreading loader

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

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

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

等待UIThread不建议它使应用程序看起来像滞后或卡住。布伦德尔在编辑中提出了很好的观点。

答案 3 :(得分:0)

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

所以这是你应该做的:

  • 使用async任务作为静态内部类,从您的activity / fragment中对内容提供程序进行异步调用。
  • 在AsyncTask doInBackground()方法中,您可以放置​​函数来检索游标并在那里处理数据,这样您最终返回List<Object>对象就是我的情况下返回的模型(联系人)。 / LI>
  • 在AsyncTask的onPostExecute()方法中,您只需将检索到的数据列表传递给您正在使用的任何视图(在我的情况下,它再次是List<Contact>以及您的mainThread所在的位置正在接收数据,只有当数据准备就绪时才需要处理数据。

AsyncTask让你的生活更轻松,因为它们有一个字符串结构来处理从MainThread传递数据到后台单独的Thread,然后将数据从后台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
            }
        }
    }
}