2012-02-13 6 views
0

私のアプリケーションにバグがあります。本当に変わっていますが、再現するのは簡単です。ダイアログボタンのOnClickListenerが長い処理で2回呼び出されました

活動にこのコードを試してみてください。

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"ボタンをクリックするとOKです。ログには示しています

<- myIncrement : 0 
-> myIncrement : 1000000 

しかし、あなたはボタン「テスト」を繰り返しクリックすると、onClickListenerは2回以上呼び出されます。

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

このexempleはちょうどあなたが私を理解させることです問題。

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

は、ファイルの書き込みとビューの変更を伴う長い処理であり、もう1つはサーバー上での同期の処理です。私はonClickメソッドのブール値を変更するなど、多くの変更を試みましたが、成功しませんでした。

提案する前にあなたの答えを確認してください。また、あなたのアプリケーションでこれを試してください。クリックが長い処理を引き起こした場合は、何度もクリックしてみてください。

答えて

1

UIスレッドで長期実行タスクを開始しようとしていますが、これは完全に禁止されています。タスクが5秒以上実行されると、このようなバグやANRも発生する可能性があります。したがって、長時間実行されているタスクの場合は、別のスレッドを作成する必要があります。 AsyncTaskクラスを使用することをおすすめします。非常に使いやすく、UIスレッドと同期して、アプリケーションが停止していないことをユーザーに示すからです。お役に立てれば。これに

+0

私はどういたしまして、 – Bourbon

+0

@Bourbon :-)今それをしようとします! – Egor

+0

ありがとう、本当に便利です! – Bourbon

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"); 
関連する問題