ラベル Android の投稿を表示しています。 すべての投稿を表示
ラベル Android の投稿を表示しています。 すべての投稿を表示

2011年7月22日金曜日

Android 2.3.4のSDKってどこさ?

ふとAndroid 2.3.4のSDKってリリースされてないのかと思い、Android SDKツールのアップデートをかけてみたんだけど「Android 2.3.4」は出てこない。

おかしいなぁと思ってググってみたところ、他にも同じ境遇の人を発見。でも続報はないみたい(残念

ひょっとして公開されてないのかなぁと思ったけど、Android SDK and AVD Managerで、Google APIsをインストールすればいいだけなのかもしれない。Google APIs Add-onは、ManagerのAvailable packagesから次のよう辿ってインストール。

Available packages  └ Third party Add-ons    └ Google Inc.      └ Google APIs by Google Inc., Android API 10, revision 2

で、インストールしたAPIのAVDを作成する。するとManager上ではプラットフォームのバージョン表記は「2.3.3」のままだけど、エミュレータを起動して端末の情報を表示してみると「2.3.4」となっていた。コレか?

Settings → About phone → Android version
Android version 2.3.4

SDK Platform Android 2.3.3, API 10, revision 1やGoogle APIs by Google Inc., Android API 10, revision 1の方の端末情報は「2.3.3」なので、Google APIsのrevison 2の方を使えばいいのかな?ホントかなぁ?でも、他にアップデートで出てこないし。

てーか、分かりにくいって。全然気が付かなかった。Manager上のプラットフォームの表示も「2.3.4」にしてくれればいいのに。。。




公式のリリースノートにはちゃんとGoogle APIs Add-Onをアップデートしてねって記載されてるじゃん。なんだよ。英語力なさすぎだろオレ。。。

To get started developing or testing against Android 2.3.4, use the Android SDK Manager to download the latest version of the Google APIs Add-On into your SDK.

2011年5月14日土曜日

enum列挙子をプロセス間通信でやり取りする方法

enumがParcelableならそのまま渡せるんだけど、調べても大して見つからない。 カスタムクラスにenum定数を持たせる方法とかはあったんだけど、 AIDLインタフェースの引数に直接enum定数をやり取りする情報は見つからない。 そんなに需要がないんだろうか。。。

たとえば、こんなenum型があったとして、

public enum EnumTest {
  ENUM_1, ENUM_2, ENUM_3;
}

こんな感じでAIDLのインタフェースとやり取りしたい場合があるんだけど、

package sample.test;

import sample.test.EnumTest;

interface TestService {
  void test(in EnumTest e);    // エラー
}

これは当然EnumTestがParcelableを実装していないのでエラーになる。

でも、enumも実際は特殊なクラスなんだから、おそらくParcelableを実装したらいいんだろうなと予測はできる。 というわけで、やってみた。

まずは、Parcelableを実装したenumを作成する。

public enum ParcelableEnumTest implements Parcelable {
  ENUM_1, ENUM_2, ENUM_3;

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    // StringでParcelに書き出す
    dest.writeString(this.name());
  }

  public static final Parcelable.Creator<ParcelableEnumTest> CREATOR = 
      new Parcelable.Creator<ParcelableEnumTest>() {
        @Override
        public ParcelableEnumTest[] newArray(int size) {
          return new ParcelableEnumTest[size];
        }

        @Override
        public ParcelableEnumTest createFromParcel(Parcel source) {
          // StringでParcelから読み出してenumに変換する
          return ParcelableEnumTest.valueOf(source.readString());
        }
      };
}

次に、同パッケージにAIDLファイルを作成。

package sample.test;

parcelable ParcelableEnumTest;

そんでもって、AIDLインタフェースで引数にParcelableを実装したenumを指定する。

package sample.test;

import sample.test.ParcelableEnumTest;

interface TestService {
  void test(in ParcelableEnumTest e);
}

するとまぁ一応Serviceをバインドしてenumをやり取りできたんだが、こんなんであってんのかね?

Parcelへの書き込みと読み出しには、一旦Stringを経由して行っているので、読み出しはちょっと効率が悪いかもしれない。 enumって確かSerializableだから、Parcel#writeSerializable()Parcel#readSerializable()でもいけるかもと思ったんだけど、ダメだった。

そもそもenumじゃなくて、intのクラス定数(static final int)を使った方がパフォーマンス的に有利だし、面倒が少なそう。 enumにimplementsを書くのも気持ち悪いし、公式ドキュメントにもパフォーマンスを意識するならenum使うなって書いてあった気がするしね*1。 実用的ではないんだろう。

だから、enum列挙子でやり取りしたいっていう需要がないのかなぁ。

参考

Android Interface Definition Language (AIDL) | Android Developers
Designing for Performance | Android Developers
Android - Avoid Enums


^1:と思ったら、いつの間にかDesigning for PerformanceからAvoid Enumsの項目が消えてた。 どういうこと?VMが改良されて今では気にしなくても良くなったりしたのかな? 昔書いてあった内容はLinuxtopiaに残ってるっぽい。