skimemo


skimemo - 日記/2013-11-01/AlertDialogでOKが押されたらプログレスダイアログを出して処理をする

_ AlertDialogでOKが押されたらプログレスダイアログを出して処理をする

普通、ダイアログの処理はこんなふうに書きますよね。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 
 
 
-
|
-
-
!
!
!
 
 
 
AlertDialog ddg = new AlertDialog.Builder(context)
.setTitle("タイトル")
.setMessage("メッセージ")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int whichButton) {
        // 処理
        doImport();
    }
})
.setNegativeButton(R.string.cancel, null)
.create();
ddg.show();


でも、この「処理」が長いので、プログレスダイアログを出したいとします。
で、onClickの部分をこんな風に書いてみますが、これではうまくいきません。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 
-
|
|
|
|
|
|
|
-
!
|
|
!
@Override
public void onClick(DialogInterface dialog, int whichButton) {
    ProgressDialog progressDialog;
    progressDialog = new ProgressDialog(context);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setMessage("処理中....");
    progressDialog.setCancelable(true);
    progressDialog.show();
 
    // 処理
    doImport();
 
    progressDialog.dismiss();
}


実際には、以下のような流れになってしまいます。

  1. AlertDialogのOKを押下
  2. 処理が実行
  3. AlertDialogが消える

どうやら、AlertDialogが表示されているためにプログレスダイアログが表示されないようです。
また、onClick(){}の処理が完了しないとAlertDialogが閉じてくれません。(onClickの中でddg.dismiss()とかやってもダメです)

これを解決するためには、onClick()の処理は速やかに完了した上で、別にdoImport()を実行する必要があります。
つまり、別スレッドにします。
コードにするとこんな感じです。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 
 
-
|
-
-
-
|
-
|
!
!
!
!
 
 
 
AlertDialog ddg = new AlertDialog.Builder(context)
.setTitle("タイトル")
.setMessage("メッセージ")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int whichButton) {
        // 処理
        (new Thread( new Runnable() {
            @Override
            public void run() {
                doImport();
            }
        })).start();
    }
})
.setNegativeButton(R.string.cancel, null)
.create();
ddg.show();


処理側はこんな風に書きます。
ただし、プログレスダイアログはUIスレッドに依頼する必要がありますので、Handlerを使用します。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
-
-
!
-
!
-
!
!
 
-
-
-
|
-
-
|
!
!
!
!
-
-
-
|
-
|
|
|
|
|
!
!
!
private void doImport() {
    // プログレス表示
    displayProgressDialog();
    // 処理
        :
    // プログレス消去
    dismissProgressDialog();
}
 
private void dismissProgresDialog() {
    // handlerを作ったスレッドへRunnable()をpostする
    handler.post(new Runnable() {
        @Override
        public void run() {
            if( null != progressDialog && progressDialog.isShowing() ){
                progressDialog.dismiss();
            }
        }
    });
}
private void displayProgressDialog() {
    // handlerを作ったスレッドへRunnable()をpostする
    handler.post(new Runnable() {
        @Override
        public void run() {
            progressDialog = new ProgressDialog(context);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setMessage(context.getResources().getString(R.string.importing));
            progressDialog.setCancelable(true);
            progressDialog.show();
        }
    });
}


handlerは、事前にUIスレッドでnewしておく必要があります。
onCreate()内で良いでしょう。
何故 displayProgressDialog() などの中でnewしてはいけないかは、ここを読むと大変よくわかります。


その名もプログレス(笑)。
一見すごい技術なのかと思ったんですが、
単に遮断してるだけみたいなので、
アルミホイルとか挟んでも同じような・・・。
Category: [android] - 22:28:02

2014-03-14 (金) 06:04:24

 
Last-modified: 2014-04-02 (水) 21:05:23 (2364d)