30
ANDROID HACKS #26 サササササササ ササ ササ Twitter : @ahyask Blog : http://mou.yatte.nai 22/05/22 1

Android Hacks - 合宿 Service

Embed Size (px)

DESCRIPTION

「Android Hacks ―プロが教えるテクニック & ツール」(株式会社ブリリアントサービス 著)を教材とした勉強会でのまとめ資料です。http://www.oreilly.co.jp/books/9784873114569/

Citation preview

Page 1: Android Hacks - 合宿 Service

ANDROIDHACKS#26 サービスを使う担当:太田

Twitter : @ahyask

Blog : http://mou.yatte.nai

23/04/08

1

Page 2: Android Hacks - 合宿 Service

この資料について• この資料は下記の本をベースに勉強会で作成した資料です。

• 『 Android Hacks 』(株式会社ブリリアントサービス著、オライリー・ジャパン刊)

• この本の紹介ページが下記にあります。

• http://www.oreilly.co.jp/books/9784873114569/

23/04/08

2

Page 3: Android Hacks - 合宿 Service

今回も敵が多かった

3

Page 4: Android Hacks - 合宿 Service

23/04/08

4

Page 5: Android Hacks - 合宿 Service

23/04/08

5

Page 6: Android Hacks - 合宿 Service

アジェンダ1. Service とは

2. Service を動かす

3. Bind 後の Service 利用

4. AIDL(Android Interface Definition Language)

5. その他補足

6

Page 7: Android Hacks - 合宿 Service

1. Service とは

7

Page 8: Android Hacks - 合宿 Service

1. Service とはバックグラウンドでアプリを動かす機能

• 常駐アプリを作る• 複数フロントエンドを持つ何か

Toast クラスもサービスを利用している

• 呼び出し元 Activity が表示されていなくても表示される理由

Service はシングルトン

• Start は何度も呼べるが, Stop は一度きり• 同じものが使いまわされているだけ 8

Page 9: Android Hacks - 合宿 Service

2.Service のライフサイクル開始

• onCreate()• 一度のみ• 同じサービスを複数起動しても呼ばれない

• onStart()• 同じサービスを複数起動した都度に呼ばれる

処理実行部

• Service running な状態終了

• onDestroy()

9

Page 10: Android Hacks - 合宿 Service

3. サービスとクライアントの関係

10

サービス様

クライアント

クライアント

クライアント

Intent

ブロードキャスト

これやっといて Sir , Yes Sir!!

Sir , Yes Sir!!Sir , Yes Sir!!

サービスからクライアントへは Intent を発行できる

Page 11: Android Hacks - 合宿 Service

3. サービスとクライアントの関係

11

サービス様

クライアント

クライアント

クライアント

クライアントは Bind 後にアクションをお願いできる

Bind

お願いしたいことがあるのです

が…

言ってみたまえ

Page 12: Android Hacks - 合宿 Service

4.Bind のライフサイクル

Bind 時

• onBind()

処理部

Bind 開放時

• onUnbind()

12

Page 13: Android Hacks - 合宿 Service

2. Service を動かす

13

Page 14: Android Hacks - 合宿 Service

1. Activity からサービスを   start するIntent は作っておきましょう

• Intent i = new Intent(this,UpdateService.class);

サービスを開始

• Context.startService(i);• 本当は一度でも start していればいらないはず• Android による kill 対策としてはとりあえず呼んでおく• この時サービス側では

onCreate() (初回のみ) , onStart() (毎回)が呼ばれる

サービスを終了

• Context.stopService(i);• Service.stopSelf();

• Service が自分を停止することも可能• 終了時にサービス側では onDestroy() が呼ばれる

14

Page 15: Android Hacks - 合宿 Service

2. Activity からサービスを   bind するサービスを bind

• Context.bindService(i, connection, Context.BIND_AUTO_CREATE);• connection についてはあとで触れる• BIND オプションについてもあとで触れる

• サービス側では onBind() が呼ばれるサービスを unbind

• unbindService(connection);• サービス側では onUnbind() が呼ばれる• サービスは残り続ける

• いつでも bindService() で bind しなおせる• 他のプロセスから bind することもできる• 全ての bind が unbind されていないと Service は停止できない

15

Page 16: Android Hacks - 合宿 Service

3. Bind 時のオプションContext.BIND_AUTO_CREATE

• 基本的にこのオプションが用いられる• サービスが立ち上がっていない場合に立ち上げてくれる• サービス側の挙動

• onCreate(),onBind() の順に呼ばれる• onStart() は呼ばれない

他のオプション

• まあ使ってるのを見ない• BIND_DEBUG_UNBIND

• debug オンリー. debug 出力を垂れ流すので本番ではやらない• unbind しわすれによるリークを発見しやすくする

• BIND_NOT_FOREGROUND• メモリ管理的には Android の機構に準拠する• CPU 利用優先度を Foreground 相当まで昇格することを制限する

16

Page 17: Android Hacks - 合宿 Service

3. Bind 後の Service 利用

17

Page 18: Android Hacks - 合宿 Service

1. ServiceConnection文字通りのコネクションとして考えればよい

• 接続してる相手にコマンド発行するくらいのノリで以下のコールバックを持つ

• onServiceConnected()• コネクション成立時• IBinder オブジェクトを受け取る

• サービス側にコールバックするためのインタフェース• onServiceDisconnected()

• コネクション切断時

注意

• onServiceConnected() はコネクション確立まで呼ばれない• bindService() から Service が使えるまでに時間的ラグがある• すぐに onServiceConnected() 呼ばれるならコールバックに

しないでしょう常識的に考えて

18

Page 19: Android Hacks - 合宿 Service

2. Ibinder の定義bind 時に Service から取得する何か

• ServiceConnection.onServiceConnection() コールバック経由

• Service との通信は IBinder を介して行う

実際は Service.onBind() の戻り値

• どのようなアクセス法を提供するかは onBind() の実装で決定できる

19

Page 20: Android Hacks - 合宿 Service

3. やってみるService 側の定義

• public class MyService extends Service {(略)@Override public IBinder onBind(Intent intent)    { return new LocalBinder(); }

class LocalBinder extends Binder {    MyService getService() { return MyService.this; } }

public void somemethod(){ // 呼び出される Service 側のメソッド }

}

20

Page 21: Android Hacks - 合宿 Service

3. やってみる呼び出し側の定義

• public class MyActivity extends Activity {(略)MyService myservice;

private void startServiceMethod(){ // どっかから呼んでもらう   Intent i = new Intent(this,MyService.class);   bindService(i, conn, Context.BIND_AUTO_CREATE);}

private void someServiceCall(){ // どっかから呼んでもらう   myservice.somemethod();}

private MyConnection conn = new ServiceConnection() {   @Override    public void onServiceConnected(ComponentName name, IBinder

binder) {     myservice = ((MyService.LocalBinder)binder).getService();    }   @Override    public void onServiceDisconnected(ComponentName name) {      myservice = null;   }}

}21

Page 22: Android Hacks - 合宿 Service

4. AIDL

Android Interface Definition Language

22

Page 23: Android Hacks - 合宿 Service

1. サービスの種類Local Service

• 同一プロセス内の Service• そのプロセス内で start したもの

• 直接 Service の参照を取得できる• 今までの手法• AIDL いらない

Remote Service

• 他プロセスになっている Service• 他のアプリケーション , パッケージで start したもの

• 直接 Service の参照を取得できない• AIDL 必要

23

Page 24: Android Hacks - 合宿 Service

2. AIDL とはAndroid Interface Definition Language

• RPC やデータのやり取りをお手軽にやるためのもの作り方

• [File]>[New]>[File] IMyService.aidl• aidl ファイルとしたけど,内容はインタフェース宣言• interface IMyService

{ 使いたいコールバックの宣言 }

• ビルドすると勝手に AIDL コンパイラが以下を作る• IMyService.java

• public interface IMyService extends IInterface• Android組み込みの Interface• Stub extends Binder を内部に持つ

• Servlet 的な手続きを実現するために必要なもの

24

Page 25: Android Hacks - 合宿 Service

3. AIDL が作ってくれたものを使うBinder は Service.onBind() が返さなければならない

• public IBinder onBind(Intent intent){return IMyServiceBinder;

}Service中に以下も定義しておく

• private IMyService.Stub IMyServiceBinder;• IMyServiceBinder = new IMyService.Stub()

{ // IMyService で宣言した各コールバック }

呼び出し側

• どこかで IMyService mybinder; を定義しておく• ServiceConnection

• public void onServiceConnected(ComponentName name, IBinder binder) {     mybinder = IMyService.Stub.asInterface(binder);}

• 利用時• mybinder.宣言したコールバック 25

Page 26: Android Hacks - 合宿 Service

5. その他補足

26

Page 27: Android Hacks - 合宿 Service

1. receiver と filterService は Intent をブロードキャストできるので,

Activity 側で Intent を受け取るようにしておく

BroadcastReceiver

• 受け取った Intent の処理を定義IntentFilter

• Receive する Intent を宣言• IntentFilter.addAction() で Intent追加可能

Context.registerReceiver(BroadcastReceiver,IntentFilter)

• 登録Context.unregisterReceiver(BroadcastReceiver)

• 解除

27

Page 28: Android Hacks - 合宿 Service

2. Service の優先度,   Kill 可能性Android のプロセス優先度管理

• Foreground > Visible > Service > Background > Empty• Service は不可視プロセス中では優先度が高い

例外事項

• onCreate() , onStart() , onDestroy() 中は Foreground扱い• bind されている場合, bind しているクライアントのうち最

も優先度の高いものと同じ優先度• 強制的にフォアグラウンド状態に置くことも可能

• Service.startForeground()

以上から Service は Kill され難いプロセスになっている

28

Page 29: Android Hacks - 合宿 Service

3. startService   bindServiceどちらも Service を起動できるが,少し挙動が違う

Context.bindService() で起動する場合

• Context.bindService()• Service.onCreate()• Service.onBind()

• Context.unbindService()• Service.onUnbind()• Service.onDestroy()

Context.startService() で起動済みの場合

• Context.bindService()• Service.onBind()

• Context.unbindService()• Service.onUnbind()

29

Page 30: Android Hacks - 合宿 Service

参考 URL

Android Developers

• http://developer.android.com/intl/ja/index.html• http://developer.android.com/reference/android/content/

Context.html#BIND_DEBUG_UNBIND

@IT - 常駐アプリが作成できる Android の“サービス”とは

• http://www.atmarkit.co.jp/fsmart/articles/android07/android07_1.html

Shifft - Android のプロセス管理を知る

• http://www.shifft.in/blog/featured/android-process/

23/04/08

30