【问题标题】:Can't create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog无法在 AsyncTask 中为 ProgressDialog 调用 Looper.prepare() 的线程内创建处理程序
【发布时间】:2011-04-06 14:13:09
【问题描述】:

我不明白为什么会出现此错误。我正在使用 AsyncTask 在后台运行一些进程。

我有:

protected void onPreExecute() 
{
    connectionProgressDialog = new ProgressDialog(SetPreference.this);
    connectionProgressDialog.setCancelable(true);
    connectionProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    connectionProgressDialog.setMessage("Connecting to site...");
    connectionProgressDialog.show();

    downloadSpinnerProgressDialog = new ProgressDialog(SetPreference.this);
    downloadSpinnerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    downloadSpinnerProgressDialog.setMessage("Downloading wallpaper...");
}

当我根据条件进入doInBackground()时:

[...]    
connectionProgressDialog.dismiss();
downloadSpinnerProgressDialog.show();
[...]

每当我尝试downloadSpinnerProgressDialog.show() 时,我都会收到错误消息。

各位有什么想法吗?

【问题讨论】:

    标签: java android runtime-error progressdialog looper


    【解决方案1】:

    show()方法必须从User-Interface (UI) thread中调用,而doInBackground()运行在不同的线程上,这是设计AsyncTask的主要原因。

    您必须通过onProgressUpdate()onPostExecute() 致电show()

    例如:

    class ExampleTask extends AsyncTask<String, String, String> {
    
        // Your onPreExecute method.
    
        @Override
        protected String doInBackground(String... params) {
            // Your code.
            if (condition_is_true) {
                this.publishProgress("Show the dialog");
            }
            return "Result";
        }
    
        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            connectionProgressDialog.dismiss();
            downloadSpinnerProgressDialog.show();
        }
    }
    

    【讨论】:

    • 这对我没有用,只是尝试了“AlertDialog.Builder builder = new AlertDialog.Builder(context);”并添加了构建器的配置。试图在 onProgressUpdate 中显示这一点会导致完全相同的错误。有什么想法吗?
    • 感谢 Konstantin,我没有意识到您可以使用 publishProgress() 以任何变量类型覆盖 onProgressUpdate。真的帮了我,简单地更新吐司消息。
    【解决方案2】:

    我遇到了类似的问题,但通过阅读这个问题,我认为我可以在 UI 线程上运行:

    YourActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            alertDialog.show();
        }
    });
    

    似乎对我有用。

    【讨论】:

    • getActivity().runOnUiThread(this::mymethod);谢谢,效果很好。
    【解决方案3】:

    我也很难完成这项工作,我的解决方案是同时使用 hyui 和 konstantin 的答案,

    class ExampleTask extends AsyncTask<String, String, String> {
    
    // Your onPreExecute method.
    
    @Override
    protected String doInBackground(String... params) {
        // Your code.
        if (condition_is_true) {
            this.publishProgress("Show the dialog");
        }
        return "Result";
    }
    
    @Override
    protected void onProgressUpdate(String... values) {
    
        super.onProgressUpdate(values);
        YourActivity.this.runOnUiThread(new Runnable() {
           public void run() {
               alertDialog.show();
           }
         });
     }
    
    }
    

    【讨论】:

    • 我认为在 onProgressUpdate() 中完成的操作会自动在 UI 线程上运行
    【解决方案4】:
    final Handler handler = new Handler() {
            @Override
            public void handleMessage(final Message msgs) {
            //write your code hear which give error
            }
            }
    
    new Thread(new Runnable() {
        @Override
        public void run() {
        handler.sendEmptyMessage(1);
            //this will call handleMessage function and hendal all error
        }
        }).start();
    

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 2017-03-07
      • 2014-11-04
      • 1970-01-01
      相关资源
      最近更新 更多