回答編集履歴
5
こっちもだ・・・
answer
CHANGED
@@ -75,7 +75,9 @@
|
|
75
75
|
@Override
|
76
76
|
public void onPause() {
|
77
77
|
super.onPause();
|
78
|
+
if (mPrgDlg != null) {
|
78
|
-
|
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
|
-
|
173
|
+
mPrgDlg.dismiss(); // ProgressDialogも消すならこれも必要
|
174
|
+
}
|
171
175
|
handler.removeCallbacks(runnable); // postDelayed()で登録されている処理を取り消し
|
172
176
|
}
|
173
177
|
}
|
4
コードミス修正
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
|
-
|
80
|
+
mThread.interrupt();
|
80
|
-
|
81
|
+
mThread = null;
|
82
|
+
}
|
81
83
|
}
|
82
84
|
}
|
83
85
|
|
3
別解掲載
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
修正
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で囲む範囲を変えています。例外
|
86
|
+
runnableの実装の中で、try-catchで囲む範囲を変えています。例外が発生したら、forループの外側に飛ぶようになっています。
|
87
87
|
|
88
|
-
onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も
|
88
|
+
onPause()が呼ばれたら、Threadを止めるためにinterruput()を実行して割り込みを飛ばしています。これにより、別スレッドとして動作しているrunnableにInterruptedExceptionが飛び、ループの外に脱出します。これによってhandler.sendMessage()も呼ばれませんので、Toastが表示されることもなくなります。
|
89
89
|
|
90
90
|
こんな感じでどうでしょうか?
|
1
文章一部修正
answer
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
Handler#removeCallbacks()が有効になるのは、このHandlerに結びついているRunnableです。質問のコードにある
|
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
|
}
|