回答編集履歴

5

こっちもだ・・・

2018/04/30 17:13

投稿

keicha_hrs
keicha_hrs

スコア6766

test CHANGED
@@ -152,7 +152,11 @@
152
152
 
153
153
  super.onPause();
154
154
 
155
+ if (mPrgDlg != null) {
156
+
155
- mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
157
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
158
+
159
+ }
156
160
 
157
161
  if (mThread != null) {
158
162
 
@@ -336,7 +340,11 @@
336
340
 
337
341
  super.onPause();
338
342
 
343
+ if (mPrgDlg != null) {
344
+
339
- mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
345
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
346
+
347
+ }
340
348
 
341
349
  handler.removeCallbacks(runnable); // postDelayed()で登録されている処理を取り消し
342
350
 

4

コードミス修正

2018/04/30 17:13

投稿

keicha_hrs
keicha_hrs

スコア6766

test CHANGED
@@ -154,9 +154,13 @@
154
154
 
155
155
  mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
156
156
 
157
+ if (mThread != null) {
158
+
157
- mThread.interrupt();
159
+ mThread.interrupt();
158
-
160
+
159
- mThread = null;
161
+ mThread = null;
162
+
163
+ }
160
164
 
161
165
  }
162
166
 

3

別解掲載

2018/04/30 17:04

投稿

keicha_hrs
keicha_hrs

スコア6766

test CHANGED
@@ -177,3 +177,167 @@
177
177
 
178
178
 
179
179
  こんな感じでどうでしょうか?
180
+
181
+
182
+
183
+ ---
184
+
185
+
186
+
187
+ 別解として、Threadを使わず遅延処理にHandler#postDelayed()を用いて、質問の目的通りHandler#removeCallbacks()によって取り消す例も記します。このように、Handlerに結びついている処理ならばremoveCallbacks()によって取り消せます。
188
+
189
+
190
+
191
+ ```Java
192
+
193
+ public class MainActivity extends AppCompatActivity {
194
+
195
+ /**
196
+
197
+ * プログレスバー
198
+
199
+ */
200
+
201
+ private ProgressDialog mPrgDlg;
202
+
203
+ public final int minutes = 600;
204
+
205
+ private int count;
206
+
207
+
208
+
209
+ @Override
210
+
211
+ public void onCreate(Bundle savedInstanceState) {
212
+
213
+ super.onCreate(savedInstanceState);
214
+
215
+ setContentView(R.layout.activity_main);
216
+
217
+
218
+
219
+ // 実行中ダイアログの生成・初期化
220
+
221
+ mPrgDlg = new ProgressDialog(this);
222
+
223
+ mPrgDlg.setTitle("スレッド実行中");
224
+
225
+ mPrgDlg.setMessage("しばらくお待ちください。");
226
+
227
+ mPrgDlg.setIndeterminate(false);
228
+
229
+ mPrgDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
230
+
231
+ mPrgDlg.setMax(100); // 最大値
232
+
233
+ mPrgDlg.incrementProgressBy(0); // 初期値
234
+
235
+
236
+
237
+ // ボタンクリック処理
238
+
239
+ Button btnStart = (Button) findViewById(R.id.btn);
240
+
241
+ btnStart.setOnClickListener(new View.OnClickListener() {
242
+
243
+ public void onClick(View v) {
244
+
245
+ // ダイアログ表示
246
+
247
+ mPrgDlg.show();
248
+
249
+
250
+
251
+ count = 0;
252
+
253
+ // 100ミリ秒後に実行する処理を登録(初回)
254
+
255
+ handler.postDelayed(runnable, 100);
256
+
257
+ }
258
+
259
+ });
260
+
261
+ }
262
+
263
+
264
+
265
+ /**
266
+
267
+ * スレッド処理
268
+
269
+ */
270
+
271
+ Runnable runnable = new Runnable() {
272
+
273
+ @Override
274
+
275
+ public void run() {
276
+
277
+ count++;
278
+
279
+ mPrgDlg.setProgress(count);
280
+
281
+
282
+
283
+ if (count < 100) {
284
+
285
+ // countが目的の回数未満なら、100ミリ秒後にこの処理を再実行するように登録
286
+
287
+ handler.postDelayed(this, 100);
288
+
289
+ } else {
290
+
291
+ Message msg = new Message();
292
+
293
+ msg.arg1 = 0;
294
+
295
+ handler.sendMessage(msg);
296
+
297
+ }
298
+
299
+ }
300
+
301
+ };
302
+
303
+
304
+
305
+ /**
306
+
307
+ * スレッドの終了を受信するハンドラ
308
+
309
+ */
310
+
311
+ private Handler handler = new Handler() {
312
+
313
+ @Override
314
+
315
+ public void handleMessage(Message msg) {
316
+
317
+ // 実行中ダイアログを閉じる
318
+
319
+ mPrgDlg.dismiss();
320
+
321
+ Toast.makeText(MainActivity.this, "遅延ボタンが押されました", Toast.LENGTH_LONG).show();
322
+
323
+ }
324
+
325
+ };
326
+
327
+
328
+
329
+ @Override
330
+
331
+ public void onPause() {
332
+
333
+ super.onPause();
334
+
335
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
336
+
337
+ handler.removeCallbacks(runnable); // postDelayed()で登録されている処理を取り消し
338
+
339
+ }
340
+
341
+ }
342
+
343
+ ```

2

修正

2018/04/29 15:22

投稿

keicha_hrs
keicha_hrs

スコア6766

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- 今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。ちょっといろいろ改修したコードを下記に記します(今回は先に動作検証しました(^^;)。
5
+ 今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。改修してみたコードを下記に記します(今回は先に動作検証しました(^^;)。
6
6
 
7
7
 
8
8
 
@@ -168,11 +168,11 @@
168
168
 
169
169
 
170
170
 
171
- runnableの実装の中で、try-catchで囲む範囲を変えています。例外を受けたら、forループの外側に飛ぶようになっています。
171
+ runnableの実装の中で、try-catchで囲む範囲を変えています。例外が発生したら、forループの外側に飛ぶようになっています。
172
172
 
173
173
 
174
174
 
175
- onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も実行さなくなりので、Toastが表示されることもなくなります。
175
+ onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も呼ばれませんので、Toastが表示されることもなくなります。
176
176
 
177
177
 
178
178
 

1

文章一部修正

2018/04/29 09:33

投稿

keicha_hrs
keicha_hrs

スコア6766

test CHANGED
@@ -1,10 +1,8 @@
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
 
4
4
 
5
5
  今回の目的を果たすには、動作中のThreadをいかに中断させるかという方向で考えた方がいいでしょう。ちょっといろいろ改修したコードを下記に記します(今回は先に動作検証しました(^^;)。
6
-
7
-
8
6
 
9
7
 
10
8
 
@@ -154,7 +152,7 @@
154
152
 
155
153
  super.onPause();
156
154
 
157
- mPrgDlg.dismiss();
155
+ mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
158
156
 
159
157
  mThread.interrupt();
160
158