回答編集履歴

8

コード修正

2021/12/03 19:26

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -26,7 +26,9 @@
26
26
 
27
27
  次のようなコードにすれば、実行時のプログラムの動作が logcat に出ますので、画面を off にしてみたりして確認してみてください。
28
28
 
29
- Handler で post するオブジェクトを remove できるように使い回すようにし、 count をオブジェクト移動させることでスレッド実行にはまた最初からなるようにしています。
29
+ Handler で post するオブジェクトを念の為 remove るようにし、 count をタイマースレッド定義することで再始動の count のリセットとしています。
30
+
31
+ スレッドの停止も interrupt に対応しました。
30
32
 
31
33
 
32
34
 
@@ -134,71 +136,81 @@
134
136
 
135
137
  if(thread != null) {
136
138
 
137
- Thread t = thread;
139
+ thread.interrupt();
140
+
141
+ try {
142
+
143
+ thread.join();
144
+
145
+ Log.d("MainActivity","thread join.");
146
+
147
+ } catch (InterruptedException ignore) {
148
+
149
+ }
138
150
 
139
151
  thread = null;
140
152
 
153
+ }
154
+
155
+ }
156
+
157
+
158
+
159
+ private class CountCallback implements Runnable {
160
+
161
+ private int count;
162
+
163
+ CountCallback(int count) {
164
+
165
+ this.count = count;
166
+
167
+ }
168
+
169
+ @Override
170
+
171
+ public void run() {
172
+
173
+ textView.setText("count=" + count);
174
+
175
+ Log.d("MainActivity","CountAction count="+count);
176
+
177
+ }
178
+
179
+ }
180
+
181
+
182
+
183
+ @Override
184
+
185
+ public void run() {
186
+
187
+ Thread thisThread = Thread.currentThread();
188
+
189
+ Log.d("MainActivity","run() start. "+thisThread);
190
+
141
- t.interrupt();
191
+ int count = 0;
192
+
193
+ for(boolean stop=false; !stop; ) {
194
+
195
+ CountCallback countCallback = new CountCallback(++count);
196
+
197
+ mainHandler.post(countCallback);
142
198
 
143
199
  try {
144
200
 
145
- t.join();
201
+ thisThread.sleep(1000);
146
-
147
- Log.d("MainActivity","thread join.");
202
+
148
-
149
- } catch (InterruptedException ignore) {
203
+ } catch (InterruptedException e) {
204
+
205
+ stop = true;
150
206
 
151
207
  }
152
208
 
209
+ mainHandler.removeCallbacks(countCallback); //念の為
210
+
153
- }
211
+ }
154
-
155
- }
212
+
156
-
157
-
158
-
159
- private class CountAction implements Runnable {
160
-
161
- private int count;
162
-
163
- public void run() {
164
-
165
- count ++;
166
-
167
- textView.setText("count=" + count);
168
-
169
- Log.d("MainActivity","CountAction count="+count);
170
-
171
- }
172
-
173
- }
174
-
175
-
176
-
177
- public void run() {
178
-
179
- Log.d("MainActivity","run() start. "+Thread.currentThread());
213
+ Log.d("MainActivity","run() stop. "+thisThread);
180
-
181
- CountAction countAction = new CountAction();
182
-
183
- while(thread != null) {
184
-
185
- mainHandler.removeCallbacks(countAction);
186
-
187
- mainHandler.post(countAction);
188
-
189
- try {
190
-
191
- thread.sleep(1000);
192
-
193
- } catch (InterruptedException ignore) {
194
-
195
- }
196
-
197
- }
198
-
199
- mainHandler.removeCallbacks(countAction);
200
-
201
- Log.d("MainActivity","run() end. "+Thread.currentThread());
202
214
 
203
215
  }
204
216
 

7

コード追加

2021/12/03 19:26

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -19,3 +19,189 @@
19
19
 
20
20
 
21
21
  スクリーン on でまた 0 からカウントするのであれば、 onStart で count = 0 してからスレッドを開始すれば良いかと思います。
22
+
23
+
24
+
25
+ ----
26
+
27
+ 次のようなコードにすれば、実行時のプログラムの動作が logcat に出ますので、画面を off にしてみたりして確認してみてください。
28
+
29
+ Handler で post するオブジェクトを remove できるように使い回すようにし、 count をそのオブジェクトに移動させることでスレッド再実行時にはまた最初からとなるようにしています。
30
+
31
+
32
+
33
+ (EmptyActivity から作ったプロジェクトで、 Hello World! を表示していた TextView に ```android:id="@+id/textView"``` を加えて使っています。)
34
+
35
+
36
+
37
+ ```java
38
+
39
+ package com.teratail.q372044;
40
+
41
+
42
+
43
+ import androidx.appcompat.app.AppCompatActivity;
44
+
45
+
46
+
47
+ import android.os.*;
48
+
49
+ import android.util.Log;
50
+
51
+ import android.widget.TextView;
52
+
53
+
54
+
55
+ public class MainActivity extends AppCompatActivity implements Runnable {
56
+
57
+ private Thread thread;
58
+
59
+ private Handler mainHandler = new Handler(Looper.getMainLooper());
60
+
61
+ private TextView textView;
62
+
63
+
64
+
65
+ @Override
66
+
67
+ protected void onCreate(Bundle savedInstanceState) {
68
+
69
+ super.onCreate(savedInstanceState);
70
+
71
+ setContentView(R.layout.activity_main);
72
+
73
+
74
+
75
+ textView = findViewById(R.id.textView);
76
+
77
+
78
+
79
+ start();
80
+
81
+ }
82
+
83
+
84
+
85
+ @Override
86
+
87
+ protected void onStart() {
88
+
89
+ Log.d("MainActivity","onStart()");
90
+
91
+ super.onStart();
92
+
93
+ start();
94
+
95
+ }
96
+
97
+
98
+
99
+ @Override
100
+
101
+ protected void onStop() {
102
+
103
+ Log.d("MainActivity","onStop()");
104
+
105
+ super.onStop();
106
+
107
+ stop();
108
+
109
+ }
110
+
111
+
112
+
113
+ public void start(){
114
+
115
+ Log.d("MainActivity","start()");
116
+
117
+ if(thread == null){
118
+
119
+ thread = new Thread(this);
120
+
121
+ Log.d("MainActivity","thread start.");
122
+
123
+ thread.start();
124
+
125
+ }
126
+
127
+ }
128
+
129
+
130
+
131
+ public void stop(){
132
+
133
+ Log.d("MainActivity","stop()");
134
+
135
+ if(thread != null) {
136
+
137
+ Thread t = thread;
138
+
139
+ thread = null;
140
+
141
+ t.interrupt();
142
+
143
+ try {
144
+
145
+ t.join();
146
+
147
+ Log.d("MainActivity","thread join.");
148
+
149
+ } catch (InterruptedException ignore) {
150
+
151
+ }
152
+
153
+ }
154
+
155
+ }
156
+
157
+
158
+
159
+ private class CountAction implements Runnable {
160
+
161
+ private int count;
162
+
163
+ public void run() {
164
+
165
+ count ++;
166
+
167
+ textView.setText("count=" + count);
168
+
169
+ Log.d("MainActivity","CountAction count="+count);
170
+
171
+ }
172
+
173
+ }
174
+
175
+
176
+
177
+ public void run() {
178
+
179
+ Log.d("MainActivity","run() start. "+Thread.currentThread());
180
+
181
+ CountAction countAction = new CountAction();
182
+
183
+ while(thread != null) {
184
+
185
+ mainHandler.removeCallbacks(countAction);
186
+
187
+ mainHandler.post(countAction);
188
+
189
+ try {
190
+
191
+ thread.sleep(1000);
192
+
193
+ } catch (InterruptedException ignore) {
194
+
195
+ }
196
+
197
+ }
198
+
199
+ mainHandler.removeCallbacks(countAction);
200
+
201
+ Log.d("MainActivity","run() end. "+Thread.currentThread());
202
+
203
+ }
204
+
205
+ }
206
+
207
+ ```

6

追加

2021/12/03 15:47

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -15,3 +15,7 @@
15
15
  start() / stop() メソッドはライフサイクルの onStart() / onStop() メソッドではありませんので、ご提示のコードでは全く実行されないですね。
16
16
 
17
17
  onStart()/ onStop() であれば(手元で実際に確認した所では)実機のスクリーンが off の状態で AndroidStudio で実行すると onStart() の後即 onStop() 実行されますので、 onStart でスレッドを開始し onStop でスレッドを停止させれば、スクリーン off 時はカウントが止まり、スクリーン on でまたカウントするようになると思います。
18
+
19
+
20
+
21
+ スクリーン on でまた 0 からカウントするのであれば、 onStart で count = 0 してからスレッドを開始すれば良いかと思います。

5

修正

2021/12/03 15:30

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -14,4 +14,4 @@
14
14
 
15
15
  start() / stop() メソッドはライフサイクルの onStart() / onStop() メソッドではありませんので、ご提示のコードでは全く実行されないですね。
16
16
 
17
- onStart()/ onStop() であれば(手元で実際に確認した所では)実機のスクリーンが off の状態で AndroidStudio で実行すると onStart() の後即 onStop() 実行されますので、 onStart でスレッドを開始し onStop でスレッドを停止させれば、スクリーン off 時はカウントが止まり、スクリーン on で最初からカウントするようになると思います。
17
+ onStart()/ onStop() であれば(手元で実際に確認した所では)実機のスクリーンが off の状態で AndroidStudio で実行すると onStart() の後即 onStop() 実行されますので、 onStart でスレッドを開始し onStop でスレッドを停止させれば、スクリーン off 時はカウントが止まり、スクリーン on でまたカウントするようになると思います。

4

勘違い修正

2021/12/03 15:28

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -10,12 +10,8 @@
10
10
 
11
11
 
12
12
 
13
- ----
13
+ 少し勘違いしていました。すいません。
14
14
 
15
- リーンOn/Off を検出する方法につきして
15
+ start() / stop() メソッドはライフサイonStart() / onStop() メソッドではありせんので、ご提示のコードで全く実行されないですね。
16
16
 
17
- [(Android)スクリーンのON/OFFを検出する](https://iyemon018.hatenablog.com/entry/2017/12/28/012030)
18
-
19
- という記事がありました。
20
-
21
- (4年前の記事なので今も出来るのかは分かりません。私はやったことがありませんので^^; )
17
+ onStart()/ onStop() であれば(手元で実際に確認した所では)実機のスクリーンが off 状態で AndroidStudio で実行すると onStart() の後即 onStop() 実行されますので、 onStart でスレッドを開始し onStop でスレッドを停止させれば、スクリーン off 時はカウントが止まり、スクリーン on で最初からカウントするようになると思います。

3

修正

2021/12/03 15:24

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -18,4 +18,4 @@
18
18
 
19
19
  という記事がありました。
20
20
 
21
- (私はやったことがありません)
21
+ (4年前の記事なので今も出来るのかは分かりません。私はやったことがありませんので^^; )

2

追加

2021/12/03 10:23

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -7,3 +7,15 @@
7
7
  stop() での thread 変数の null 化の **後** に、スレッドに対して割り込みをかけて sleep を抜けさせ、 while (thread!=null) を通って停止するまで join して確実にスレッドを止まったことを確認したほうが良いのではないでしょうか。
8
8
 
9
9
  また、MainLoop に post した処理がまだ未処理で残っている場合もありますので、出来ればそれをキャンセルするべきかもしれませんが…現状ではそのオブジェクトは作りっぱなしですので修正が大変かもしれません。
10
+
11
+
12
+
13
+ ----
14
+
15
+ スクリーンの On/Off を検出する方法につきましては、
16
+
17
+ [(Android)スクリーンのON/OFFを検出する](https://iyemon018.hatenablog.com/entry/2017/12/28/012030)
18
+
19
+ という記事がありました。
20
+
21
+ (私はやったことがありません。)

1

誤字

2021/12/03 10:22

投稿

jimbe
jimbe

スコア12744

test CHANGED
@@ -4,6 +4,6 @@
4
4
 
5
5
  スレッドが停止していないということですね。
6
6
 
7
- stop() での thread 変数の null 化の **後** に、スレッドに対して割り込みをけて sleep を抜けさせ、 while (thread!=null) を通って停止するまで join して確実にスレッドを止まったことを確認したほうが良いのではないでしょうか。
7
+ stop() での thread 変数の null 化の **後** に、スレッドに対して割り込みをけて sleep を抜けさせ、 while (thread!=null) を通って停止するまで join して確実にスレッドを止まったことを確認したほうが良いのではないでしょうか。
8
8
 
9
9
  また、MainLoop に post した処理がまだ未処理で残っている場合もありますので、出来ればそれをキャンセルするべきかもしれませんが…現状ではそのオブジェクトは作りっぱなしですので修正が大変かもしれません。