Androidプロジェクトの罠

皆で使う共通のライブラリィを参照してアプリケーションを開発するのは、Eclipseを使う場合に限らず極めて普通だが、Androidの場合、ことADTを使って開発をする場合、このやり方は注意が必要だ。

ADTのAndroidプロジェクトは特定のディレクトリ(res)配下に、認識できる形式のXMLを配置すると、(自動的にビルドにしてあれば)即座にXMLを解釈し独自の"R.java"というJavaソースコードに変換する。

  • Layout用XMLから変換されたR.java
public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
    public static final class id {
        public static final int EditText01=0x7f050001;
        public static final int LinearLayout01=0x7f050000;
        public static final int MapView01=0x7f050003;
        :
    }
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        :
        :
    }
}

IDを持つGUIの要素はR.Java中のリソース種別毎に定義されたインナークラスの定数値として管理されることになるが、アプリケーション、ライブラリィ問わず、この定数をハンドルとしてGUI要素やグラフィクス要素、文字列を参照するイディオムを多用する。(リソースに変更があった場合、古いリソース名で参照しているコードはコンパイル時のエラーになる。実行時にエラーが発生してしまうのと比べて、良い方法だと思う。)

  • R.Javaの定数により参照されるGUI(View)要素
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    
    setContentView(R.layout.main);
    MapView mapView = (MapView) findViewById(R.id.MapView01);

リソースXMLJavaに変換するために、ライブラリィといえどもAndroidプロジェクトの形式、ディレクトリ構成にした場合、他のAndroidアプリケーションのプロジェクトから参照する場合※1、注意が必要である。というのもAndroidプロジェクトはそれ自体、ビルドと同時に.apkアーカイブを生成する、つまりは端末側にプッシュ(インストール)する対象となるため、

ライブラリィ.apk
アプリケーション.apk

と、別個に.apkイメージをエミュレータにインストールすることになり、アプリケーションはライブラリィのクラスを参照できなくなってしまう。

なので、Androidの場合は、ライブラリィをAndroidプロジェクトとして作成したならば、プロジェクトではなく、ソースコードとして参照する必要がある。※2 というか、この方法以外に良い方法があるのだろうか。


※1 Javaのビルド・パス -> プロジェクト -> ビルドパス上に必要なプロジェクト->追加する事を指す
※2 Javaのビルド・パス -> ソース -> ビルドパス上に必要なソースフォルダ->ソースのリンクで追加する事を指す