2012-07-03 93 views
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(),則會同步(this){}我在應用程序上獲得強制關閉,但是如果我使用它,它永遠不會返回,它似乎從來沒有通知()線程。 這個想法是從線程返回true或false,但只有當用戶按下了一些按鈕。

+0

你爲什麼把事情這麼複雜? 「」我知道你不能阻止UI線程「」但你實際上正在做大部分工作(創建一個對話)在UI線程中,這是線程的主線程。 你在做簡單對話時面臨什麼問題(沒有如此複雜)? –

+0

如果您閱讀了這個問題,您將看到我不想簡單地創建一個對話框,我想等待用戶輸入的對話框,但當然不會阻止UI線程 – Andres

回答

0

您可以使用Interface從AlertDialog獲得通知/返回一些值。檢查我的回答here

+0

創建對話框我可以看到它,但該值永遠不會返回。 show()也創建對話框。 – Andres

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; 
    } 
+0

謝謝你我會試試,你知道另一種方式更簡單,因爲我還需要創建一個新線程才能使用它嗎? – Andres

+0

@Andres:是的,你仍然需要線程。不幸的是,我並不是真的對android有多瞭解,我只是基於我的java線程知識​​來回答,所以我不能真正提出任何更好的方法... – Tudor

+0

非常感謝您的幫助,但它沒有奏效:/我已經調用它在一個線程新線程(新的Runnable(){如果(createDialogConfirm()){...}})。但是當我點擊任何按鈕時,我會得到:「java.lang.RuntimeException:無法在未調用Looper.prepare()」的線程中創建處理程序。而且我還嘗試將新的Thread()放在方法內部,以更清晰的方式調用它,但我無法通過這種方式返回值。 – Andres

相關問題