Hatena::Groupandroid

Droidくん「JavaとXMLの魔境、Androidフレームワークの世界へようこそ!」

 | 

2010-07-01

たとえばActivityがForegroundのときだけ定期的にAsyncTaskを実行したいとすると

22:17 | はてなブックマーク - たとえばActivityがForegroundのときだけ定期的にAsyncTaskを実行したいとすると - Droidくん「JavaとXMLの魔境、Androidフレームワークの世界へようこそ!」

Androidといえばマルチタスクでバックグラウンドで常駐処理!!!などと喧伝されており

バックグラウンドで定期処理とかやるときはandroid.app.Serviceというのを使おう!!!といたるところで書かれている昨今。


しかし色々と調べたところ

たとえば、あるアプリケーションのUIを、バックグラウンドで走る定期的な処理に応じて更新するみたいな用途にはServiceは若干オーバースペックぎみのようで、

Serviceで音楽を再生してそこからがんばって呼び出し元ActivityのViewを更新しているような事例もチラホラ見当たるもののかなり大変そう。。

実際のところjava.util.TimerTask + AsyncTaskのほうが、UIスレッド上のViewをじかに触れるしシンプルなのではないかと思いました。


ところが実現しようとすると意外と厄介(かつググっても情報がない状態)だったのでメモ


何も考えずにonCreateのなかでjava.util.TimerTaskのscheduleメソッドでAsyncTaskをよびっぱなしにすると、どんどん非同期タスクが生成されて大変な事になる。

Homeに戻ってもまだまだガンガンスレッドが生成実行されている。

これは画面から消えてもActivityが実行されつづけているから。


activityにisForegroundみたいなメソッドがあれば、それがtrueのときだけtaskを実行するというふうにできるがそういうのもないらしく、

さらにactivity isFinishingメソッドはfinishメソッドでactivityが止められたとき専用のフラグのようなので、

ここではisForegroundというクラス変数を用意して、onXxxというActivityのライフサイクルが変わったことを知らせるメソッドが呼ばれるたびにその変数を書き換えることにしてみた。

いちおうこれで期待通りの動きをしてくれる。

public class HogeAndroid extends Activity {
    public static boolean isForeground;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        isForeground = true;
        Timer timer = new Timer(false);
        // このActivityが最全面かどうか5秒おきに確認して最前面のときだけ非同期でタスクを実行
        timer.schedule(new TimerTask() {
            public void run() {
                if (isForeground){
                    SomeAsyncTask task = new SomeAsyncTask(HogeAndroid.this);
                    task.execute("hoge");
                    }
                }
            },0, 5000);
   }

    @Override
    protected void onResume(){
		isForeground = true;
		super.onResume();
    }
    
    @Override
    protected void onStop(){
		isForeground = false;
		super.onStop();
    }
    
    @Override
    protected void onPause() {
		isForeground = false;
		super.onPause();
    }
}

これでUIの更新に関する処理は、SomeAsyncTaskのonPostExecute()にゴリゴリ書いて問題ないはず。

ServiceやHandlerやcallbackやADILを記述するよりは楽に済ませられる。


最初は単純にonPause()の部分でAsyncTask task.cancel();を実行するようにしてみたが、これでは次々生成されるタスクの新規生成自体は全然止められなかったのでこうした。(これはTimerTaskを停止してないので当然)

このコードだと5秒おきにTimerTaskを起動しているが、onXxxのたびにTimerTaskのcancel()とかscheduleとかをやったほうが実行時のコストは下がるかもしれない。。(が、コードはこれより複雑になりそう)


Serviceがどうしても必須となるシーンは、Activityが完全にonDestroyで停止されてしまったあとも実行しつづけてユーザーにNotificationを送ったりしたい場合くらいかも?

※追記:Serviceが必須になる状況がほかにもあった。ActivityのUIThread と完全に独立したバックグラウンド処理でスレッドを動かしつづけて、その処理結果に応じてActivityを更新したいようなとき。AsyncTaskは呼び出されるたびに実行され毎回その結果を反映して終了ようなタイプの処理にしか使えない。ので、終了が存在しないようなパターン(通信待ち受け処理とか)でなにかが起きる度にUIに反映されせる、といった状態には向いていない。。。

単に非同期の処理を定期的に実行してUI更新したい、とかならServiceなしでも上に書いた方法で可能。

LuckyLucky 2012/02/15 21:16 Son of a gun, this is so heflpul!

aokoylzaokoylz 2012/02/16 18:09 3Lenaa <a href="http://zkqpwsvsjezf.com/">zkqpwsvsjezf</a>

mubcuvmubcuv 2012/02/16 23:47 AXBebo , [url=http://vxdzofynkobj.com/]vxdzofynkobj[/url], [link=http://jhzsxmerhoel.com/]jhzsxmerhoel[/link], http://omhjlfsmndax.com/

ElenaElena 2013/11/22 20:11 Stay inartmfoive, San Diego, yeah boy!

JooJoo 2013/11/23 04:46 Yeah that's what I'm talking about <a href="http://noljyi.com">ba-i-bnyce</a> work!

SamSam 2013/11/25 10:27 Check that off the list of things I was <a href="http://dppaizybg.com">coesufnd</a> about.

SamSam 2013/11/25 10:27 Check that off the list of things I was <a href="http://dppaizybg.com">coesufnd</a> about.

SamSam 2013/11/25 10:27 Check that off the list of things I was <a href="http://dppaizybg.com">coesufnd</a> about.

BankBank 2015/10/09 18:33 Yeah, that's the tikcet, sir or ma'am

SunielSuniel 2015/10/11 12:34 Until I found this I <a href="http://jqsvuzzoyxm.com">thhgout</a> I'd have to spend the day inside.

ObitObit 2015/10/13 08:48 Wow! Great <a href="http://titxci.com">thikinng!</a> JK

AmandaAmanda 2015/10/13 15:52 This post has helped me think things thgrouh http://sunlork.com [url=http://xuknivff.com]xuknivff[/url] [link=http://zhpoxiqvpz.com]zhpoxiqvpz[/link]

GalalGalal 2015/12/20 03:13 I seaechrd a bunch of sites and this was the best.

OriosOrios 2015/12/20 10:57 Stay <a href="http://exfagmebtr.com">inrmtoafive,</a> San Diego, yeah boy!

AnandAnand 2015/12/23 21:56 I actually found this more enrintaiteng than James Joyce. http://mwnqudf.com [url=http://eidmantrl.com]eidmantrl[/url] [link=http://otyaqzjmlm.com]otyaqzjmlm[/link]

ゲスト



トラックバック - http://android.g.hatena.ne.jp/yuiseki/20100701
 |