質問するログイン新規登録

回答編集履歴

5

こっちもだ・・・

2018/04/30 17:13

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -75,7 +75,9 @@
75
75
  @Override
76
76
  public void onPause() {
77
77
  super.onPause();
78
+ if (mPrgDlg != null) {
78
- mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
79
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
80
+ }
79
81
  if (mThread != null) {
80
82
  mThread.interrupt();
81
83
  mThread = null;
@@ -167,7 +169,9 @@
167
169
  @Override
168
170
  public void onPause() {
169
171
  super.onPause();
172
+ if (mPrgDlg != null) {
170
- mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
173
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
174
+ }
171
175
  handler.removeCallbacks(runnable); // postDelayed()で登録されている処理を取り消し
172
176
  }
173
177
  }

4

コードミス修正

2018/04/30 17:13

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -76,8 +76,10 @@
76
76
  public void onPause() {
77
77
  super.onPause();
78
78
  mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
79
+ if (mThread != null) {
79
- mThread.interrupt();
80
+ mThread.interrupt();
80
- mThread = null;
81
+ mThread = null;
82
+ }
81
83
  }
82
84
  }
83
85
 

3

別解掲載

2018/04/30 17:04

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -87,4 +87,86 @@
87
87
 
88
88
  onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も呼ばれませんので、Toastが表示されることもなくなります。
89
89
 
90
- こんな感じでどうでしょうか?
90
+ こんな感じでどうでしょうか?
91
+
92
+ ---
93
+
94
+ 別解として、Threadを使わず遅延処理にHandler#postDelayed()を用いて、質問の目的通りHandler#removeCallbacks()によって取り消す例も記します。このように、Handlerに結びついている処理ならばremoveCallbacks()によって取り消せます。
95
+
96
+ ```Java
97
+ public class MainActivity extends AppCompatActivity {
98
+ /**
99
+ * プログレスバー
100
+ */
101
+ private ProgressDialog mPrgDlg;
102
+ public final int minutes = 600;
103
+ private int count;
104
+
105
+ @Override
106
+ public void onCreate(Bundle savedInstanceState) {
107
+ super.onCreate(savedInstanceState);
108
+ setContentView(R.layout.activity_main);
109
+
110
+ // 実行中ダイアログの生成・初期化
111
+ mPrgDlg = new ProgressDialog(this);
112
+ mPrgDlg.setTitle("スレッド実行中");
113
+ mPrgDlg.setMessage("しばらくお待ちください。");
114
+ mPrgDlg.setIndeterminate(false);
115
+ mPrgDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
116
+ mPrgDlg.setMax(100); // 最大値
117
+ mPrgDlg.incrementProgressBy(0); // 初期値
118
+
119
+ // ボタンクリック処理
120
+ Button btnStart = (Button) findViewById(R.id.btn);
121
+ btnStart.setOnClickListener(new View.OnClickListener() {
122
+ public void onClick(View v) {
123
+ // ダイアログ表示
124
+ mPrgDlg.show();
125
+
126
+ count = 0;
127
+ // 100ミリ秒後に実行する処理を登録(初回)
128
+ handler.postDelayed(runnable, 100);
129
+ }
130
+ });
131
+ }
132
+
133
+ /**
134
+ * スレッド処理
135
+ */
136
+ Runnable runnable = new Runnable() {
137
+ @Override
138
+ public void run() {
139
+ count++;
140
+ mPrgDlg.setProgress(count);
141
+
142
+ if (count < 100) {
143
+ // countが目的の回数未満なら、100ミリ秒後にこの処理を再実行するように登録
144
+ handler.postDelayed(this, 100);
145
+ } else {
146
+ Message msg = new Message();
147
+ msg.arg1 = 0;
148
+ handler.sendMessage(msg);
149
+ }
150
+ }
151
+ };
152
+
153
+ /**
154
+ * スレッドの終了を受信するハンドラ
155
+ */
156
+ private Handler handler = new Handler() {
157
+ @Override
158
+ public void handleMessage(Message msg) {
159
+ // 実行中ダイアログを閉じる
160
+ mPrgDlg.dismiss();
161
+ Toast.makeText(MainActivity.this, "遅延ボタンが押されました", Toast.LENGTH_LONG).show();
162
+ }
163
+ };
164
+
165
+ @Override
166
+ public void onPause() {
167
+ super.onPause();
168
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
169
+ handler.removeCallbacks(runnable); // postDelayed()で登録されている処理を取り消し
170
+ }
171
+ }
172
+ ```

2

修正

2018/04/29 15:22

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  Handler#removeCallbacks()が有効になるのは、このHandlerに結びついているRunnableです。参考にしたページでは、Handler#postDelayed()の引数に与えたRunnableをremoveCallbacks()で削除しようとしています。それに対し、今回の質問のコードにあるRunnableはThreadに結びついているもので、Handlerとは何の関係も持っていません。ですからここでのremoveCallbacks()は何も機能しません。
2
2
 
3
- 今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。ちょっといろいろ改修したコードを下記に記します(今回は先に動作検証しました(^^;)。
3
+ 今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。改修してみたコードを下記に記します(今回は先に動作検証しました(^^;)。
4
4
 
5
5
  ```Java
6
6
  public class MainActivity extends AppCompatActivity {
@@ -83,8 +83,8 @@
83
83
 
84
84
  ```
85
85
 
86
- runnableの実装の中で、try-catchで囲む範囲を変えています。例外を受けたら、forループの外側に飛ぶようになっています。
86
+ runnableの実装の中で、try-catchで囲む範囲を変えています。例外が発生したら、forループの外側に飛ぶようになっています。
87
87
 
88
- onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も実行さなくなりので、Toastが表示されることもなくなります。
88
+ onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も呼ばれませんので、Toastが表示されることもなくなります。
89
89
 
90
90
  こんな感じでどうでしょうか?

1

文章一部修正

2018/04/29 09:33

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,8 +1,7 @@
1
- Handler#removeCallbacks()が有効になるのは、このHandlerに結びついているRunnableです。質問のコードにあるrunnableはThreadに結びつものであり、Handlerとは無縁です。ですからここでのremoveCallbacks()は何の意味持ちません。
1
+ Handler#removeCallbacks()が有効になるのは、このHandlerに結びついているRunnableです。参考にしたページでは、Handler#postDelayed()の引数に与えたRunnableをremoveCallbacks()で削除しようとしています。それに対し、今回の質問のコードにあるRunnableはThreadに結びついているもので、Handlerとは何の関係も持っていません。ですからここでのremoveCallbacks()は何も機能しません。
2
2
 
3
3
  今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。ちょっといろいろ改修したコードを下記に記します(今回は先に動作検証しました(^^;)。
4
4
 
5
-
6
5
  ```Java
7
6
  public class MainActivity extends AppCompatActivity {
8
7
  /**
@@ -76,7 +75,7 @@
76
75
  @Override
77
76
  public void onPause() {
78
77
  super.onPause();
79
- mPrgDlg.dismiss();
78
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
80
79
  mThread.interrupt();
81
80
  mThread = null;
82
81
  }