私が持っているAndroidの本には載っていないのだが、今は非同期で動かすというか、ワーカースレッドみたいにして動かしやすいようにAsyncTaskなるものがあるそうだ。
使い方はそこまで難しくなく、ネットに出てくるサンプル通りに書けば動いた。
しばらく非同期部分を動かしたかったので無限ループにすると、通らないルートが発生するためか怒られた。
適当にif文とbreakを追加すると言われなくなったのだが、そんな対応でよいのだろうか。。。
無限ループも、ぐるぐる回すと忙しすぎるので、Thread.sleep()で10秒ごとに回すようにした。
さて、そのときに非同期部分をキャンセルさせたかったら、どうするとよいのだろうか?
最初に試したのは、フラグだった。
停止フラグを用意して、ボタンを押したらフラグを立てる。
無限ループ内では停止フラグを見るようにして、立っていたらbreakで抜ける。
まあ、動くには動くのだが、sleepしている間は待っておくしかないので、ちょっとわびしい。
どうやら、Thread.sleep()は、Thread.interrupted()を呼ぶと抜けるらしい。
シグナルみたいなものか。
そうしていくうちに、isCancelled()があることに気付いた。
AsyncTaskを継承するとcancel()が追加され、これを呼んでやるとisCancelled()が立つので、無限ループでもこれでbreakすればよいようだ。
cancel()を呼ぶと、onCancelled()が呼び出されるようになっている。
じゃあ、さっきのThread.interrupted()をここで呼んでやるようにしておこう。
が、そこまでしなくても、cancel(true)としてやるとThread.interrupted()が呼ばれるようになっているみたいだ。
「mayInterruptIfRunning」では、わからんかったなぁ。
"thread"はAsyncTaskのことを指しているのかと思っていたよ。。
DDMS...じゃなくて、Android Device Monitorでアプリのスレッドを見ると、AsyncTaskをnewしていくとこういう風に見えた。
doInBackground()を抜けても数は変わらなかったが、StatusがWaitになった。
ArrayList<>に保持していたものもclear()しているから、消えると思ったんだけどね。
まだGCのタイミングじゃないと言うことか。
あるいは、1つずつ消さないといけないのか。。。
- ArrayList#clear()だけ
- 残ったまま
- さらに=nullもする
- 残ったまま
Android Device Monitorから「Cause GC」としても残っているので、消える対象になっていないのだろうという気がする。
うーん、この辺りをどうしてよいのか思いつかないところが哀しいですな。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。