2012-02-13 79 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"); 
相关问题