【问题标题】:Thread on AlertDialog警报对话框上的线程
【发布时间】:2013-06-14 16:34:24
【问题描述】:

我创建了继承自 AlertDialog 的类。此类启动线程,通过互联网检查一些值(操作时间长)。该对话框有一个按钮(POSITIVE_BUTTON)。在线程结束之前,应该禁用此按钮。但我不知道如何从线程中启用此按钮。

我的代码:

public MyDialog(Context context) {
    super(context);
    View view = getLayoutInflater().inflate(R.layout.dialog, null);
    setView(view);

    getButton(BUTTON_POSITIVE).setEnabled(false);

    new Thread(new Runnable() {
        public void run() {
            // Long operation time code
            getButton(BUTTON_POSITIVE).setEnabled(true); // CRASH!!!
        }
    }).start();    
}

错误表明我从另一个线程更改视图。而且我不能使用runOnUIThread 方法,因为它不会在AlertDialog 中退出。 我该怎么办?

【问题讨论】:

  • 你能在你的构造函数中传递一个 Activity 吗?

标签: android multithreading dialog


【解决方案1】:

如果您能够在构造函数中传递 Activity,只需执行以下操作:

public class MyDialog extends AlertDialog {

    public MyDialog(Activity act) {
        super(act);
        View view = getLayoutInflater().inflate(R.layout.layout_launch, null);
        setView(view);

        getButton(BUTTON_POSITIVE).setEnabled(false);

        act.runOnUiThread(new Runnable() {
            public void run() {
                // Long operation time
                getButton(BUTTON_POSITIVE).setEnabled(true); // CRASH!!!
            }
        });  
    }

}

【讨论】:

  • 不会通过在 UI 线程上运行长操作来阻塞它吗?在我看来,只有 getButton(BUTTON_POSITIVE).setEnabled(true) 应该在 UI 线程上运行...
  • @mbrenon 对。但最好的计划是在此处实施AsyncTask 以执行长时间操作。
【解决方案2】:

您不能从不同于 UI 线程的线程管理 UI 元素

 public MyDialog(Context context) {
    super(context);
    final View view = getLayoutInflater().inflate(R.layout.dialog, null);
    setView(view);

    getButton(BUTTON_POSITIVE).setEnabled(false);

    new Thread(new Runnable() {
        public void run() {
            // Long operation time code
           view.post(new Runnable() {
              public void run() {
                 View button = getButton(BUTTON_POSITIVE);
                  if (button != null)
                     button.setEnabled(true); // CRASH!!!
              }
           }
        }
    }).start();    
}

您还想检查getButton() 返回的空值

【讨论】:

    【解决方案3】:

    假设你传递的上下文是调用活动,那么:

    public MyDialog(Context context) {
        super(context);
        View view = getLayoutInflater().inflate(R.layout.activity_main, null);
        setView(view);
    
        getButton(BUTTON_POSITIVE).setEnabled(false);
    
        ((Activity) context).runOnUiThread(
        new Thread(new Runnable() {
            public void run() {
                // Long operation time
                getButton(BUTTON_POSITIVE).setEnabled(true); // CRASH!!!
            }
        }));
    }
    

    【讨论】:

    • 方法不对,没用。函数setEnabled 仍然从线程中调用。
    猜你喜欢
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多