2012年1月31日火曜日

AIDLによる Service ⇔ Activity間通信


●AIDLとは?
→android上でプロセス間通信を行うためのもの
 Service側に実装されたコールバック用のインターフェースを
 Activityが受け取ることで、Serviceの処理を呼び出すことが可能
 逆に ServiceからActivityのメソッドも呼び出せるらしい? ★ 要調査
 最初のテンプレートさえ覚えておけば、使い方は特に問題なさそう

1.AIDLファイルの作成
拡張子 .aidl のファイルを作成し、その中に下記のようにインターフェースを書く
javaソースと同じフォルダに置く

 
interface IServiceMethod
{
void CallServiceMethod();
}

2.サービスの実装

class MyService extends Service implements IServiceMethod
{
    @Override
    public IBinder onBind(Intent intent) {
        if(IServiceMethod.class.getName().equals(intent.getAction())){
            // IServiceMethodのインスタンスを返す
            return isvc;
        }
        return null;
    }

private IServiceMethod.Stub isvc = new IServiceMethod.Stub()
{
public void CallServiceMethod() throws RemoteException {
// Service側で実行する処理を実装
}
};
}

ビルドすると gen フォルダに自動生成された IServiceMethod.javaが出来る。
中身を見ると、Stub という名前の内部抽象クラスがあり、.aidl ファイルで宣言したメソッドが定義される。
このインターフェースを実装した Stabクラスのインスタンスを bind時に返せばOK。


3.Activityの実装
 
public class IPCMain extends Activity {

IServiceMethod aidl = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // MyServiceにbindする
        Intent i = new Intent(this, android.study.kai.MyService.class);
        bindService(i, serviceConnection, BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy()
    {
    super.onDestroy();
    // MyServiceからアンバイド
    unbindService(serviceConnection);
    }

    private ServiceConnection serviceConnection = new ServiceConnection()
    {
    // サービスとの接続時に呼ばれる
        public void onServiceConnected(ComponentName name, IBinder ibinder)
        {
        // Ibinder インターフェースから、AIDLのインターフェースにキャストするメソッドらしい
        aidl = IServiceMethod.Stub.asInterface(ibinder);
        }

    // サービスとの切断時に呼ばれる
        public void onServiceDisconnected(ComponentName name)
        {
        aidl = null;
        }
    };
}

bindServiceと、unbindServiceを呼び出し、サービスと接続/切断する
Serviceのインターフェースは、bind成功時に呼ばれる
インターフェースから取得できる

●bindService
bindService(i, serviceConnection, BIND_AUTO_CREATE);

引数1: インデント。サービスのクラスを指定する?
引数2: ServiceConnectionの実装を指定する
    ServiceConnectionは、サービス接続、切断時に呼ばれる
    コールバック用のインターフェースである。
    接続時に、onBindで返したサービス側のインターフェースを取得できる
引数3: BIND_AUTO_CREATEを指定することでServiceが未起動の時に起動される

●unbindService
unbindService(serviceConnection);
引数1:ServiceConnectionの実装を指定する

0 件のコメント:

コメントを投稿