java - 对 AsyncTask 中的 UI 操作进行故障排除(OnProgressDialog、Toasts)

标签 java android multithreading android-asynctask

我试图在 AsyncTask 中显示 ProgressDialog,但收到错误无法在未调用 Looper.prepare() 的线程内创建处理程序。 于是我搜索了一下,发现here以前有人遇到过这个问题。

我采用了您可以在其中看到的第二个答案,并以这种方式实现了我的 AsyncTask。现在一切都很好,但我想一定有更好的方法来显示该对话框。

这是我修复后的 AsyncTask

private class MyAsyncTask extends AsyncTask<Void, Void, ArrayList</*SomeObject*/>> {
    ProgressDialog mDialog;

    private MyAsyncTask() {
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                mDialog = new ProgressDialog(getActivity());
            }
        });
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mDialog.setMessage("AsyncTask is starting...");
                mDialog.show();
            }
        });
    }

    @Override
    protected ArrayList</*SomeObject*/> doInBackground(Void... params) {
        // some non UI related code...
    }

    @Override
    protected void onPostExecute(ArrayList</*SomeObject*/> someObjects) {
        super.onPostExecute(exams);
        // some code...
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mDialog.dismiss();
            }
        });
    }
}

我的问题是

  1. 有更好的方式来显示对话框吗?

  2. 为什么我只在这个特定的 AsyncTask 中收到错误? (下面的代码效果很好)

我运行了您可以在下面看到的 AsyncTask 一百次,它从未崩溃,而第一个从未成功执行。一定有什么我看不见的东西!

private class MyAsyncTask extends AsyncTask<String, Void, String> {
    private final ProgressDialog dialog = new ProgressDialog(mContext);

    private LoginConnectTask() {
    }

    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setMessage("aMessage");
        dialog.show();
    }

    protected String doInBackground(String... strings) {
        return fancyFunction(strings[0], strings[1]);
    }

    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (s != null) {
            Toast.makeText(mContext, s, Toast.LENGTH_LONG).show();
        }
        dialog.dismiss();
    }
}

最佳答案

doInBackground() 之外的所有 AsyncTask 方法都在 UI 线程 上运行。因此,没有理由或不想在 AsyncTask 内部使用 runOnUiThread(),而且它通常会导致问题(据我所知)。

因此,您的构造函数中不需要它,并且在这种情况下似乎根本不需要构造函数。另外,在 onPreExecute() 中,您可以只显示 Dialog,因为它在 UI Thread 上运行。与在 onPostExecute() 中关闭它相同。

所以直接回答你的问题,

Is there a better way to display the dialog?

不,您在第二段代码中执行此操作的方式完全正常

Why I get the errors only in this particular AsyncTask? (the code below works well)

在没有看到所有代码的情况下不确定确切的原因,但正如 Raghunandan 所说,“当您从非 ui 线程更新 ui 时通常会发生错误”但是,如上所述,没有理由使用 runOnUiThread( ) 位于 AsyncTask 内。至少我不知道有什么原因,而且在大多数情况下也没有原因。

关于java - 对 AsyncTask 中的 UI 操作进行故障排除(OnProgressDialog、Toasts),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20789826/

相关文章:

android - 如何让 gradle 编译本地版本的毕加索

c# - 将参数传递给 Backgroundworker 错误处理程序

java - Java中对 volatile 对象进行非 volatile 引用的行为

android - 滑动标签不起作用,我在屏幕上看不到

android - 当我对其应用 crashlytics 时应用程序崩溃

java - 是否可以在一种方法中获取锁并从另一种方法中释放它?

java - JFrame没有实时更新

java - 使用 Rhino 从 Clojurescript 生成 Java 类

java - 图:找到一种算法来确定矩形迷宫中从一点到另一点的最短路径?

java - VBox 的拖放功能