Android:Service 小山 圭
Agenda Serviceとは何でしょう? 最も簡単なService Notification Callback まとめ
AndroidのService from Anatomy of an Android Application A Service is code that is long-lived and runs without a UI. UIが無い長生きするコード Activityと違いフロントに表示されなくても実行 つまり常駐して実行を続けられる 音楽の再生などに用います
Serviceの実体 android.app.Service Activityと同じくContextを継承 Taskの1要素 Context#startService()で起動 bindService()で起動中のサービスに接続、起動していなければ起動 stopService()にて停止
Intent ServiceもIntentをキーに起動します Serviceを止めるキーもIntentです 設定により他のActivityに公開可能 Intentは江川さんにおまかせします><
Serviceのライフタイム 基本はstartされてからstopされるまで システムがメモリ状況により殺す場合有り ただし殺害対象の優先順位は低い bindしているclientが複数いる間はstopしても止まらない
<service> AndroidMenifest.xmlにタグの記述が必要 process属性 細粒度のセキュリティ設定が可能 例) <service android:name=".PlayerService" /> process属性 この属性値に名前を付けるとremote local:起動したActivitiyと同じプロセス remote:新しいプロセス 細粒度のセキュリティ設定が可能
ハンズオン
流れ SDカードイメージを作る エミュレータをSDカードをマウントして起動 単純なプレーヤ 単純なサービス 単純なNotification
PATHの設定 Linux, Mac OS X, Cygwin Windows cd $ANDROID_HOME/tools PATH=$PATH:$PWD Windows cd %ANDROID_HOME%\tools path %path%;%cd%
SDカードイメージを作る mksdcard <size> <file> サイズはKとMが指定可 ファイルの拡張子は自動で付きません エミュレータは8M以下のSDカードを使えません 例)サイズ1Gバイトでファイル名が”1G.img” mksdcard 1024M 1G.img
エミュレータを起動 SDカードをマウントして起動する 例) ファイル名”1G.img”のイメージを使用 emulator –sdcard 1G.img Eclipseでは起動オプションに入れられる
mp3をSDカードにコピー adb push <local> <remote> SDカードは/sdcardにマウントされます 例) SDカードに全てのmp3をコピー adb push *.mp3 /sdcard adb shellにて確認 adb shell でLinuxのshが起動します cd /sdcard ls –l mp3がない場合、 /system/media/audio/ringtones
MediaScannerを起動 MediaScannerによりDBの更新 DBはsqlite3形式 メディアファイルの情報がDB化 ホーム画面より DevTools→Media Scanner DBはsqlite3形式 /data/data/com.android.providers.media/databases/external-label.db SDKはsqlite3が/system/xbinにあります
最も単純なPlayer 演奏中にバックボタンを押すことで演奏が停止することを確認 public class SimplePlayer extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button b = new Button(this); b.setText("Play"); b.setOnClickListener(new OnClickListener() { public void onClick(View v) { MediaPlayer mp = new MediaPlayer(); try { mp.setDataSource("/sdcard/CrazyDream.ogg"); mp.prepare(); mp.start(); } catch (Exception e) { throw new RuntimeException(e); } }); setContentView(b); 演奏中にバックボタンを押すことで演奏が停止することを確認
最も単純なサービス ActivityはServiceを起動、終了するだけ 詳細はソースで
高度なサービス
高度なサービス サービスを実行するだけでは足りない サービスに処理対象や処理内容を依頼したい サービスと通信する必要がある
IPC Interprocess Communication ActivityとServiceは別プロセスの場合有 直で呼べるとは限らない pipe? socket? 共有メモリ? プロセス間通信手段の抽象化が必要 リモートでもローカルでも同じ手段で通信したい
AIDL (1/2) ActivityとService間のInterfaceを定義 JavaのInterfaceとほぼ同じです Android Interface Definition Language ActivityとService間のInterfaceを定義 IDLは昔からあります CORBA JavaのInterfaceとほぼ同じです 違いは引数に方向性があります Interfaceを用いて通常のOOPが可能です 接続手続は非常に面倒です 一旦繋がればそれはただのインスタンス
AIDL(2/2) 拡張子 “.aidl” Eclipseではファイル作成で行う CUIではaidl 方向の記述はin,out,inout 保存すると即時でjavaにコンパイルされる CUIではaidl 方向の記述はin,out,inout 実装の実際はdocumentのAIDLを
Stub AIDLをコンパイルしたjavaに存在 呼び出される側が継承して概念としてのサービスを実装 例) 指定された曲を演奏する 呼び出す側はInterfaceとして呼出に利用
Callback ActivityがServiceに依頼するだけでは足りない ServiceがActivityに依頼する場合がある 例) 曲の再生が次に移った時に画面を更新 これをCallbackと呼ぶ 実装はAIDLを用いるので変わらない ただし実装場所が反対になる
Parcellable AcitivityとServiceでclassを共有したい 分散オブジェクト指向がしたい AndroidはJavaのSerializableを用いない Parcellableを継承して自前でシリアライズ 使ってません><
サービスの利用手順 Activity Service 作成/実行 startService(Bundle) 接続 bindService(ServiceConection) ServiceConnection.onConnect(IBinder) Interface.Stub.asInterface(IBinder) 取得 Service 登録 Service.registerCallback(Callback) サービスの利用 Service.method() コールバックの利用 Callback.method()
MP3Player完成版の解説
注意点 サービスの必要性を良く考えよう CPUとストレージは進化している 電池は進化していない Androidは省電力を最も重視している 本当にServiceが必要か? Intentで即時起動、即時終了で良い可能性は?
まとめ Serviceによる常駐アプリ作成法を学んだ AIDLを用いたIPCの方法を学んだ 以下について大体理解した MediaPlayer Notification ContentProvider
謝辞 アイコン提供 写真とMP3の提供 http://www.iconarchive.com/ http://www.niconicommons.jp/