2

我一直想知道大多数应用程序如何创建确认对话框,我可以让我的工作。我知道你不能阻止 UI 线程所以我有这样的东西:

private synchronized boolean createDialogConfirm() {
        if(DEBUG) Log.i("Dialog", "createDialogConfirm()");
        // Creo un nuevo Thread que crea el cuadro de dialogo TODO: no funciona la confirmacion, nunca llega al return
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Creo el dialogo con los dos botones
                AlertDialog.Builder confirm = new AlertDialog.Builder(LogicAnalizerView.this);
                confirm.setTitle("Guardar");
                confirm.setMessage("El archivo existe, sobreescribir ?");
                if(DEBUG) Log.i("Dialog", "createDialogConfirm() -> Created");

                // Boton Si
                confirm.setPositiveButton("Si", new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int whichButton) {    
                      state = true;
                      synchronized(this) { this.notifyAll(); };     // Despierta el Thread
                  }
                });

                // Boton No
                confirm.setNegativeButton("No", new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int whichButton) {
                      state = false;
                      synchronized(this) { this.notifyAll(); };
                      dialog.dismiss();   
                  }
                });
                confirm.show();
            }
        });

        if(DEBUG) Log.i("Dialog", "createDialogConfirm() - Thread created");
        try {
            synchronized(this) { wait(); }; // Queda esperando (no retorna nada) hasta que se llame a notify() en algun boton
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return state;
    }

所以我在线程(不是 UI 线程)中以这种方式使用它:

if(createDialogConfirm()){ ... }

我知道这是一种丑陋的方式,但如果您有任何我想听的人,我不知道其他方式。问题是,如果我调用 notifyAll() 或 notify() whitout synchronized(this){},我会在我的应用程序上强制关闭,但如果我使用它,它就永远不会返回,似乎永远不会 notify() 线程。这个想法是从线程返回一个真或假,但只有当用户按下某个按钮时。

4

2 回答 2

0

我相信你的问题来自你正在同步的事实,当你打电话时this,这是一个不同的对象,而notifyAll不是你打电话时wait,因为当你打电话时,notifyAll你在一个new Runnable(...)对象内。尝试在中性对象上进行同步。此外,您应该wait使用布尔条件来保护 ,以确保不会出现计时竞赛或虚假唤醒:

private synchronized boolean createDialogConfirm() {

        final Object signal = new Object(); // !
        final boolean[] shouldWait = new boolean[] { true };

        if(DEBUG) Log.i("Dialog", "createDialogConfirm()");
        // Creo un nuevo Thread que crea el cuadro de dialogo TODO: no funciona la confirmacion, nunca llega al return
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Creo el dialogo con los dos botones
                AlertDialog.Builder confirm = new AlertDialog.Builder(LogicAnalizerView.this);
                confirm.setTitle("Guardar");
                confirm.setMessage("El archivo existe, sobreescribir ?");
                if(DEBUG) Log.i("Dialog", "createDialogConfirm() -> Created");

                // Boton Si
                confirm.setPositiveButton("Si", new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int whichButton) {    
                      state = true;
                      synchronized(signal) { shouldWait[0] = false; signal.notifyAll(); }     
                  }
                });

                // Boton No
                confirm.setNegativeButton("No", new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int whichButton) {
                      state = false;
                      synchronized(signal) { shouldWait[0] = false; signal.notifyAll(); }
                      dialog.dismiss();   
                  }
                });
                confirm.show();
            }
        });

        if(DEBUG) Log.i("Dialog", "createDialogConfirm() - Thread created");
        try {
            while(shouldWait[0]) {
               synchronized(signal) { signal.wait(); }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return state;
    }
于 2012-07-03T09:30:24.140 回答
0

您可以使用Interface从您的 AlertDialog 获取通知/返回一些值。检查我的答案here

于 2012-07-03T04:52:16.560 回答