2011年5月20日金曜日

Android Service使ってバックグランド処理

サービスでバックグランド処理させることができるらしい。何分起きに何かを確認とかそういった処理をできる。

さっそくサンプル作って理解する。

Serviceを継承したクラスを作る。onCreate,onDestoryでは固定メッセージ、onStartではintentでgetしたメッセージをToastで表示するだけ。
public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "create service", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStart(Intent intent, int StartId) {
        String message = intent.getStringExtra("Message");
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    //5秒休んで終了
                    sleep(5 * 1000);
                    stopSelf();
                } catch (InterruptedException e) {
                }
            }
        };
        t.start();
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "destroy service", Toast.LENGTH_SHORT).show();
    }
}
AndroidManifest.xmlにserviceを追加する。下記をapplication内に記述。
<service android:name="MyService" />

後はこのサービスをstartServiceで起動してやれば良いだけ。
  Intent intent = new Intent(MainActivity.this, MyService.class);
  startService(intent);
ただ、これだと一定時間毎に起動ってことにはならない。一回起動して終わり。なので、AlarmManagerで繰り返し起動するようにsetする。
        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent(MainActivity.this, MyService.class);
                intent.putExtra("Message", "Hello Service");
                PendingIntent service = PendingIntent.getService(
                        MainActivity.this, 0, intent, 0);

                long first = System.currentTimeMillis() + 1 * 1000;
                long interval = 10 * 1000;
                AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
                am.setRepeating(AlarmManager.RTC, first, interval, service);
            }
        });
        mStopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent(MainActivity.this, MyService.class);
                PendingIntent service = PendingIntent.getService(
                        MainActivity.this, 0, intent, 0);
                AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
                am.cancel(service);
            }
        });
これでスタートボタンを押して1秒後に起動、5秒後に終了メッセージ出力。さらに5秒後(起動からだとintervalの10秒後)にまた起動…を繰り返す。ストップボタンを押してcancelするまでは。例えMainActivityが前面にいなくても。
こんな感じでHome画面でもServiceが動いてるのがわかる。

AlarmManagerのsetRepeatingで繰り返して何分毎に処理ってことにしたけど、ServiceをstopSelfしないで無限ループでスリープさせつつ一定時間毎に処理させる方法もあるよう。

bindあたりがまだ理解できてないけど、とりあえずのメモ。