Android_Service

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要素

サービスの実装はServiceを継承
 Context#startService()で起動
 bindService()で起動中のサービスに接続、
起動していなければ起動
 stopService()にて停止

Intent
ServiceもIntentをキーに起動します
 Serviceを止めるキーもIntentです
 設定により他のActivityに公開可能


Intentは江川さんにおまかせします><
Serviceのライフタイム
基本はstartされてからstopされるまで
 システムがメモリ状況により殺す場合有り

• ただし殺害対象の優先順位は低い

bindしているclientが複数いる間はstopして
も止まらない
<service>

AndroidMenifest.xmlにタグの記述が必要
• 例)


<service android:name=".PlayerService" />
process属性
• この属性値に名前を付けるとremote
• local:起動したActivitiyと同じプロセス
• remote:新しいプロセス

細粒度のセキュリティ設定が可能
ハンズオン
流れ
SDカードイメージを作る
 エミュレータをSDカードをマウントして起動
 単純なプレーヤ
 単純なサービス
 単純なNotification

PATHの設定

Linux, Mac OS X, Cygwin
• cd $ANDROID_HOME/tools
• PATH=$PATH:$PWD

Windows
• cd %ANDROID_HOME%\tools
• path %path%;%cd%
SDカードイメージを作る

mksdcard <size> <file>
• サイズはKとMが指定可

例) 128M, 16K
• ファイルの拡張子は自動で付きません
• エミュレータは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化
• ホーム画面より


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)

Android Interface Definition Language

ActivityとService間のInterfaceを定義
• IDLは昔からあります


CORBA
JavaのInterfaceとほぼ同じです
• 違いは引数に方向性があります

Interfaceを用いて通常のOOPが可能です
• 接続手続は非常に面倒です
• 一旦繋がればそれはただのインスタンス
AIDL(2/2)
拡張子 “.aidl”
 Eclipseではファイル作成で行う

• 保存すると即時で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
作成/実行
startService(Bundle)
bindService(ServiceConection)
接続
ServiceConnection.onConnect(IBinder)
Interface.Stub.asInterface(IBinder)
取得
Service
Service.registerCallback(Callback)
登録
Service.method()
サービスの利用
Callback.method()
コールバックの利用
Service
MP3Player完成版の解説
注意点

サービスの必要性を良く考えよう
• CPUとストレージは進化している
• 電池は進化していない
• Androidは省電力を最も重視している
• 本当にServiceが必要か?
• Intentで即時起動、即時終了で良い可能性は?
まとめ
Serviceによる常駐アプリ作成法を学んだ
 AIDLを用いたIPCの方法を学んだ


以下について大体理解した
• MediaPlayer
• Notification
• ContentProvider
謝辞

アイコン提供
• http://www.iconarchive.com/

写真とMP3の提供
• http://www.niconicommons.jp/