2012-02-13 53 views
0

我的應用程序有一個錯誤,它看起來很奇怪,但很容易重現。對話框按鈕中的OnClickListener被調用兩次,處理時間很長

嘗試在活動驗證碼:

public int myIncrement = 0; 

protected Dialog onCreateDialog(int i, Bundle args) 
    { 
     if (i == DIALOG_TEST_MY_BUG) 
     { 
      AlertDialog.Builder builder = new AlertDialog.Builder(this); 
      builder.setTitle("Test"); 

      builder.setNegativeButton("Test", new DialogInterface.OnClickListener() 
      { 
       public void onClick(DialogInterface dialog, int id) 
       { 
        Log.i("Test", "<- myIncrement : " + myIncrement); 
        for (int i = 0; i < 1000000; i++) 
         myIncrement ++; 
        Log.i("Test", "-> myIncrement : " + myIncrement); 
       } 
      } 
     } 
    } 

當顯示此對話框,它的確定。當你點擊「Test」按鈕時,沒關係。日誌顯示:

<- myIncrement : 0 
-> myIncrement : 1000000 

但如果你點擊重複按鈕「測試」後,onClickListener將被稱爲2倍以上:

<- myIncrement : 0 
-> myIncrement : 1000000 
<- myIncrement : 1000000 
-> myIncrement : 2000000... 

這裏本例僅僅是爲了讓你瞭解我問題。相當於

    for (int i = 0; i < 1000000; i++) 
         myIncrement ++; 

是一個長文件寫入和視圖更改處理,另一個與服務器上的同步。我嘗試了很多變化,例如在onClick方法中更改布爾值,但沒有成功。

請在提議之前檢查您的答案。請在您的應用程序上嘗試此操作,當點擊導致長時間處理時,請嘗試點擊它多次。

回答

1

您試圖在UI線程中啓動一個長時間運行的任務,這是完全禁止的。如果任務運行時間超過5秒,它可能會導致您像這樣的錯誤和ANR。所以對於任何長時間運行的任務,你應該創建一個單獨的線程我建議使用AsyncTask類,因爲它非常易於使用,並與UI線程同步以向用戶顯示應用程序未被阻塞。希望這可以幫助。

+0

我會嘗試,現在:-) – Bourbon 2012-02-13 11:13:28

+0

@Bourbon,歡迎你! – Egor 2012-02-13 11:16:54

+0

謝謝,真的很有用! – Bourbon 2012-02-14 10:18:18

1

改成這樣:

private AlertDialog builder = null; 
protected Dialog onCreateDialog(int i, Bundle args) 
{ 
    if (i == DIALOG_TEST_MY_BUG) 
    { 
     if(builder != null && builder.isShowing() 
      return; // prevent multiple dialog instances 
     builder = new AlertDialog.Builder(this); 
     builder.setTitle("Test"); 
相關問題