Android ASync 任务 ProgressDialog 在后台线程完成之前不会显示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2702695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:00:58  来源:igfitidea点击:

Android ASync task ProgressDialog isn't showing until background thread finishes

androidandroid-asynctask

提问by Hymanbot

I've got an Android activity which grabs an RSS feed from a URL, and uses the SAX parser to stick each item from the XML into an array. This all works fine but, as expected, takes a bit of time, so I want to use AsyncActivity to do it in the background. My code is as follows:

我有一个 Android 活动,它从 URL 获取 RSS 提要,并使用 SAX 解析器将 XML 中的每个项目粘贴到一个数组中。这一切都很好,但正如预期的那样,需要一些时间,所以我想使用 AsyncActivity 在后台执行此操作。我的代码如下:

class AddTask extends AsyncTask<Void, Item, Void> {

    protected void onPreExecute() {
        pDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Retrieving data ...", true);
    }

    protected Void doInBackground(Void... unused) {
        items = parser.getItems();

        for (Item it : items) {
            publishProgress(it);
        }
        return(null);
    }

    protected void onProgressUpdate(Item... item) {
        adapter.add(item[0]);
    }

    protected void onPostExecute(Void unused) {
        pDialog.dismiss();
    }
  }

Which I call in onCreate()with

我称之为在onCreate()

new AddTask().execute();

The line items = parser.getItems()works fine - itemsbeing the arraylist containing each item from the XML. The problem I'm facing is that on starting the activity, the ProgressDialog which i create in onPreExecute()isn't displayed until afterthe doInBackground()method has finished. i.e. I get a black screen, a long pause, then a completely populated list with the items in. Why is this happening? Why isn't the UI drawing, the ProgressDialog showing, the parser getting the items and incrementally adding them to the list, then the ProgressDialog dismissing?

该行items = parser.getItems()工作正常 -items是包含 XML 中每个项目的数组列表。我现在面临的问题是,在启动活动中,ProgressDialog这是我在创造onPreExecute()不显示,直到之后doInBackground()方法完成。即我得到一个黑屏,一个长时间的停顿,然后是一个包含项目的完全填充的列表。为什么会发生这种情况?为什么 UI 绘图、ProgressDialog 显示、解析器获取项目并将它们逐步添加到列表中,然后 ProgressDialog 关闭?

采纳答案by Pentium10

This works for me

这对我有用

@Override
protected void onPreExecute() {
        dialog = new ProgressDialog(viewContacts.this);
        dialog.setMessage(getString(R.string.please_wait_while_loading));
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }

回答by jengelsma

I suspect something is blocking your UI thread after you execute the task. For example, I have seen folks do things like this:

我怀疑在您执行任务后有什么东西阻塞了您的 UI 线程。例如,我看到人们做这样的事情:

MyTask myTask = new MyTask();
TaskParams params = new TaskParams();
myTask.execute(params);
myTask.get(5000, TimeUnit.MILLISECONDS);

The get invocation here is going to block the UI thread (which presumably is spinning off the task here...) which will prevent any UI related stuff in your task's onPreExecute() method until the task actually completes. Whoops! Hope this helps.

这里的 get 调用将阻塞 UI 线程(它大概是在这里分离任务......),这将阻止任务的 onPreExecute() 方法中的任何 UI 相关内容,直到任务实际完成。哎呀!希望这可以帮助。

回答by Ziming Zhao

It is because you used AsyncTask.get()that blocks the UI thread "Waits if necessary for the computation to complete, and then retrieves its result.".

这是因为您使用AsyncTask.get()了阻止 UI 线程“如果需要等待计算完成,然后检索其结果。”。

The right way to do it is to pass Activityinstance to your AsyncTaskby constructor, and finish whatever you want to do in AsyncTask.onPostExecution().

正确的做法是通过构造函数将Activity实例传递给您AsyncTask,然后在AsyncTask.onPostExecution().

回答by GeHa

If you subclass the AsyncTask in your actual Activity, you can use the onPostExecutemethod to assign the result of the background work to a member of your calling class.

如果您在实际 Activity 中对 AsyncTask 进行子类化,则可以使用该onPostExecute方法将后台工作的结果分配给调用类的成员。

The result is passed as a parameter in this method, if specified as the third generic type.

如果指定为第三个泛型类型,则结果在此方法中作为参数传递。

This way, your UI Thread won't be blocked as mentioned above. You have to take care of any subsequent usage of the result outside the subclass though, as the background thread could still be running and your member wouldn't have the new value.

这样,您的 UI 线程就不会像上面提到的那样被阻塞。但是,您必须注意子类之外对结果的任何后续使用,因为后台线程可能仍在运行并且您的成员不会具有新值。