狠狠撸

狠狠撸Share a Scribd company logo
ANDROID HACKS #26  サービスを使う 担当:太田 Twitter : @ahyask Blog : http://mou.yatte.nai 09/19/11
この資料について この資料は下記の本をベースに勉強会で作成した資料です。 『 Android Hacks 』(株式会社ブリリアントサービス著、オライリー?ジャパン刊) この本の紹介ページが下記にあります。 http://www.oreilly.co.jp/books/9784873114569/ 09/19/11
今回も敌が多かった
09/19/11
09/19/11
アジェンダ Service とは Service を動かす Bind 後の Service 利用 AIDL(Android Interface Definition Language) その他補足
1. Service とは
1. Service とは バックグラウンドでアプリを動かす機能 常駐アプリを作る 複数フロントエンドを持つ何か Toast クラスもサービスを利用している 呼び出し元 Activity が表示されていなくても表示される理由 Service はシングルトン Start は何度も呼べるが, Stop は一度きり 同じものが使いまわされているだけ
2.Service のライフサイクル 開始 onCreate() 一度のみ 同じサービスを複数起動しても呼ばれない onStart() 同じサービスを複数起動した都度に呼ばれる 処理実行部 Service running な状態 終了 onDestroy()
3. サービスとクライアントの関係 サービス様 クライアント クライアント クライアント Intent ブロードキャスト これやっといて Sir , Yes Sir!! Sir , Yes Sir!! Sir , Yes Sir!! サービスからクライアントへは Intent  を発行できる
3. サービスとクライアントの関係 サービス様 クライアント クライアント クライアント クライアントは Bind 後にアクションをお願いできる Bind お願いしたいことがあるのですが… 言ってみたまえ
4.Bind のライフサイクル Bind 時 onBind() 処理部 Bind 開放時 onUnbind()
2. 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()  が呼ばれる
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 は停止できない
3. Bind 時のオプション Context.BIND_AUTO_CREATE 基本的にこのオプションが用いられる サービスが立ち上がっていない場合に立ち上げてくれる サービス側の挙動 onCreate(),onBind()  の順に呼ばれる onStart() は呼ばれない 他のオプション まあ使ってるのを見ない BIND_DEBUG_UNBIND debug オンリー. debug 出力を垂れ流すので本番ではやらない unbind しわすれによるリークを発見しやすくする BIND_NOT_FOREGROUND メモリ管理的には Android の機構に準拠する CPU 利用優先度を Foreground 相当まで昇格することを制限する
3. Bind 後の Service 利用
1. ServiceConnection 文字通りのコネクションとして考えればよい 接続してる相手にコマンド発行するくらいのノリで 以下のコールバックを持つ onServiceConnected() コネクション成立時 IBinder  オブジェクトを受け取る サービス側にコールバックするためのインタフェース onServiceDisconnected() コネクション切断時 注意 onServiceConnected()  はコネクション確立まで呼ばれない bindService()  から Service が使えるまでに時間的ラグがある すぐに onServiceConnected() 呼ばれるならコールバックに しないでしょう常識的に考えて
2. Ibinder の定義 bind 時に Service から取得する何か ServiceConnection.onServiceConnection() コールバック経由 Service との通信は IBinder を介して行う 実際は Service.onBind() の戻り値 どのようなアクセス法を提供するかは onBind() の実装で決定できる
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 側のメソッド   } }
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;    } } }
4. AIDL Android Interface Definition Language
1. サービスの種類 Local Service 同一プロセス内の Service そのプロセス内で start したもの 直接 Service の参照を取得できる 今までの手法 AIDL いらない Remote Service 他プロセスになっている Service 他のアプリケーション , パッケージで start したもの 直接 Service の参照を取得できない AIDL 必要
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 的な手続きを実現するために必要なもの
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. 宣言したコールバック
5.  その他補足
1. receiver と filter Service は Intent をブロードキャストできるので, Activity 側で Intent を受け取るようにしておく BroadcastReceiver 受け取った Intent の処理を定義 IntentFilter Receive する Intent を宣言 IntentFilter.addAction()  で Intent 追加可能 Context.registerReceiver(BroadcastReceiver,IntentFilter) 登録 Context.unregisterReceiver(BroadcastReceiver) 解除
2. Service の優先度,    Kill 可能性 Android のプロセス優先度管理 Foreground > Visible >  Service  > Background > Empty Service は不可視プロセス中では優先度が高い 例外事項 onCreate() , onStart() , onDestroy()  中は Foreground 扱い bind されている場合, bind しているクライアントのうち最も優先度の高いものと同じ優先度 強制的にフォアグラウンド状態に置くことも可能 Service.startForeground() 以上から Service は Kill され難いプロセスになっている
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()
参考 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/ 09/19/11

More Related Content

Android Hacks - 合宿 Service

  • 1. ANDROID HACKS #26 サービスを使う 担当:太田 Twitter : @ahyask Blog : http://mou.yatte.nai 09/19/11
  • 2. この資料について この資料は下記の本をベースに勉強会で作成した資料です。 『 Android Hacks 』(株式会社ブリリアントサービス著、オライリー?ジャパン刊) この本の紹介ページが下記にあります。 http://www.oreilly.co.jp/books/9784873114569/ 09/19/11
  • 6. アジェンダ Service とは Service を動かす Bind 後の Service 利用 AIDL(Android Interface Definition Language) その他補足
  • 8. 1. Service とは バックグラウンドでアプリを動かす機能 常駐アプリを作る 複数フロントエンドを持つ何か Toast クラスもサービスを利用している 呼び出し元 Activity が表示されていなくても表示される理由 Service はシングルトン Start は何度も呼べるが, Stop は一度きり 同じものが使いまわされているだけ
  • 9. 2.Service のライフサイクル 開始 onCreate() 一度のみ 同じサービスを複数起動しても呼ばれない onStart() 同じサービスを複数起動した都度に呼ばれる 処理実行部 Service running な状態 終了 onDestroy()
  • 10. 3. サービスとクライアントの関係 サービス様 クライアント クライアント クライアント Intent ブロードキャスト これやっといて Sir , Yes Sir!! Sir , Yes Sir!! Sir , Yes Sir!! サービスからクライアントへは Intent を発行できる
  • 11. 3. サービスとクライアントの関係 サービス様 クライアント クライアント クライアント クライアントは Bind 後にアクションをお願いできる Bind お願いしたいことがあるのですが… 言ってみたまえ
  • 12. 4.Bind のライフサイクル Bind 時 onBind() 処理部 Bind 開放時 onUnbind()
  • 14. 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() が呼ばれる
  • 15. 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 は停止できない
  • 16. 3. Bind 時のオプション Context.BIND_AUTO_CREATE 基本的にこのオプションが用いられる サービスが立ち上がっていない場合に立ち上げてくれる サービス側の挙動 onCreate(),onBind() の順に呼ばれる onStart() は呼ばれない 他のオプション まあ使ってるのを見ない BIND_DEBUG_UNBIND debug オンリー. debug 出力を垂れ流すので本番ではやらない unbind しわすれによるリークを発見しやすくする BIND_NOT_FOREGROUND メモリ管理的には Android の機構に準拠する CPU 利用優先度を Foreground 相当まで昇格することを制限する
  • 17. 3. Bind 後の Service 利用
  • 18. 1. ServiceConnection 文字通りのコネクションとして考えればよい 接続してる相手にコマンド発行するくらいのノリで 以下のコールバックを持つ onServiceConnected() コネクション成立時 IBinder オブジェクトを受け取る サービス側にコールバックするためのインタフェース onServiceDisconnected() コネクション切断時 注意 onServiceConnected() はコネクション確立まで呼ばれない bindService() から Service が使えるまでに時間的ラグがある すぐに onServiceConnected() 呼ばれるならコールバックに しないでしょう常識的に考えて
  • 19. 2. Ibinder の定義 bind 時に Service から取得する何か ServiceConnection.onServiceConnection() コールバック経由 Service との通信は IBinder を介して行う 実際は Service.onBind() の戻り値 どのようなアクセス法を提供するかは onBind() の実装で決定できる
  • 20. 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 側のメソッド } }
  • 21. 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;    } } }
  • 22. 4. AIDL Android Interface Definition Language
  • 23. 1. サービスの種類 Local Service 同一プロセス内の Service そのプロセス内で start したもの 直接 Service の参照を取得できる 今までの手法 AIDL いらない Remote Service 他プロセスになっている Service 他のアプリケーション , パッケージで start したもの 直接 Service の参照を取得できない AIDL 必要
  • 24. 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 的な手続きを実現するために必要なもの
  • 25. 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. 宣言したコールバック
  • 27. 1. receiver と filter Service は Intent をブロードキャストできるので, Activity 側で Intent を受け取るようにしておく BroadcastReceiver 受け取った Intent の処理を定義 IntentFilter Receive する Intent を宣言 IntentFilter.addAction() で Intent 追加可能 Context.registerReceiver(BroadcastReceiver,IntentFilter) 登録 Context.unregisterReceiver(BroadcastReceiver) 解除
  • 28. 2. Service の優先度,    Kill 可能性 Android のプロセス優先度管理 Foreground > Visible > Service > Background > Empty Service は不可視プロセス中では優先度が高い 例外事項 onCreate() , onStart() , onDestroy() 中は Foreground 扱い bind されている場合, bind しているクライアントのうち最も優先度の高いものと同じ優先度 強制的にフォアグラウンド状態に置くことも可能 Service.startForeground() 以上から Service は Kill され難いプロセスになっている
  • 29. 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()
  • 30. 参考 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/ 09/19/11