2008年04月18日

PIP-Android完全版

ついに、以前のエントリー「PIP-Android」で作成したAndroid版PIPを動作させる環境の作成に成功しました!!!

Androidに任意のIPを割り当てる方法」により、VMWare上に構築したCentOS4.6上で動作するAndroid と 無線LANを装備した「Zaurus Android」 の 間での動作です。


実際に動作を試した結果、一部に致命的な構造ミスがあることが判明したため、修正いたしました。
最新版は、「こちら」よりダウンロードしてください。


■Serviceにおいても、Workerスレッドへのアタッチが必要なため、修正した
●Androidにおいては、インスタンスを生成したスレッド(Workerスレッドor親スレッド)以外のスレッドから、そのインスタンスへアクセスすることが出来ません。
そのため、Handlerクラスというモノが用意されており、これを利用してアタッチします。

今回の修正では、この作法に基づいた修正を行っています。

●PIPでは、Socketの待ち受けように別のスレッドを起動しいています。そのため、上記の制限に引っかかり、ServiceやActivityのインスタンスにアクセスすることが出来ません。
そこで、下記のような変更を行いました。

・PIPAgentやMSRPAgentが、IMServiceへコールバック通知する部分を、下記のように修正
Handler#sendMessage(Message)関数を用いて、Handlerへ任意のメッセージを送信する

Handler.sendMessage(Handler.obtainMessage(0, 0, 0, new EventMessage(IMEvent.onNewSession, new Object[]{c.getCallId(), request})));

※EventMessageクラス・・・Handlerを介してやりとりするためのメッセージ。イベントの種類と引数(PIPメッセージやコールID)を保持している。


・IMService上で、上記のHandlerへのメッセージを受信し、IMServiceの任意のコールバック先関数を呼び出す

Handler#handleMessage(Message)を、Overrideして、イベントの種類に合わせて、呼び出し先メソッドの振り分けを行います。
注意点は、このHandlerのインスタンスは、Serviceのインスタンス生成の時点と同じタイミングで、生成する必要がある点です。onCreate()などのタイミングで生成してはいけません。

※IMServiceクラス内
private Handler mHandler = new Handler() {
  @Override
  public void handleMessage(Message handlerMessage) {
    // EventMessageは、存在するかチェックする。     if(handlerMessage.obj == null || !(handlerMessage.obj instanceof EventMessage)) {
      super.handleMessage(handlerMessage);
      return;
    }
    // EventMessageを取り出す。
    EventMessage msg = (EventMessage)handlerMessage.obj;
    Object[] objs = msg.getArgs();
    // イベントの種類により、IMServiceのコールバック先メソッドを選択する
    switch (msg.getEventType()) {
      case onNewSession:
        // 引数と共に、コールバックする
        imService.onNewSession((String)objs[0], (PIPMessage)objs[1]);
        break;
    (以下略)


Creative Commons License
This weblog is licensed under a Creative Commons License.