外部ライブラリのすゝめ2

引き続き外部ライブラリのすゝめ2です。
今回はAndroidの外部ライブラリの作り方です。
前回の後半でもAndroidSDKのAPIを使う外部ライブラリの作り方書きましたが
今回はリソースを使う外部ライブラリの作り方です。
完全に外部化するからには国際化なんかも済ませておきたいですね。

構成

  1. AndroidAppはAndroidLibのクラスのメソッドを呼び出します
  2. AndroidLibは自身に定義されている文字列リソースを返します
  3. AndroidAppは受け取った文字列をToastで表示します。

簡単なアプリですねー。

AndroidLib

まずはAndroidLibプロジェクトを作ります。

New Project

Project Name:AndroidLib
Build Target:Android 1.6
Application Name:AndroidLib
Package Name:jp.tomorrowkey.android.androidlib
Min SDK Version:4

Acitivtyは作らないので、Create Activityのチェックは外します。

Project Properties


is Libraryのチェックを入れます。
ここのチェックを入れるとどこが変わるかというと
default.propertiesファイルに"android.library=true"という新しいプロパティが作成されます。

AndroidManifest.xml

AndroidManifestを変更します。
applicationエレメントを削除します。
ライブラリなのでアプリ名とかアイコンとか必要ありません。
むしろあると悪さをするんで消しておくべきです。

<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="jp.tomorrowkey.android.androidlib"
  android:versionCode="1"
  android:versionName="1.0">
  <uses-sdk
    android:minSdkVersion="4" />
</manifest> 
res/layout/main.xml

削除します。
使いません。

res/values-ja/strings.xml

新しく作成します。
日本語の文字列リソースです。


  こんにちわ 明日!

res/values/string.xml

helloという項目を削除して、greetingという文字列を足します。
日本語以外の文字列リソースです。


  Hello Tomorrow!

src/jp.tomorrowkey.android.android.lib.Util.java
package jp.tomorrowkey.android.androidlib;

import android.content.Context;

public class Util {
  public static String getGreeting(Context context) {
    return context.getString(R.string.greeting);
  }
}

AndroidApp

続いてAndroidAppを作ります。

New Project

ProjectName:AndroidApp
Build Target:Android 1.6
Application Name:Android App
Package:jp.tomorrowkey.android.androidapp
Create Activity:MainActivity
Min SDK Version:4
Project Properties


Add... -> AndroidLib -> OK
でこんな感じになると思います。
ここまで終わったらAndroidLibのプロジェクトを参照ができているはずなんですが
リフレッシュしてもクリーンしてもAndroidAppからAndroidLibのクラスは参照できず…。

しょうがないのでEclipseを再起動すると表示されるようになります。

/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <Button
    android:id="@+id/btnPushMe"
    android:text="push me"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
</LinearLayout>
/src/jp.tomorrowkey.android.androidapp.MainActivity.java
package jp.tomorrowkey.android.androidapp;

import jp.tomorrowkey.android.androidlib.Util;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

  private Button btnPushMe;

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

    btnPushMe = (Button) findViewById(R.id.btnPushMe);
    btnPushMe.setOnClickListener(this);
  }

  @Override
  public void onClick(View view) {
    int id = view.getId();
    if (id == R.id.btnPushMe) {
      String greeting = Util.getGreeting(this);
      Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();
    }
  }
}

これで

すべて完成です。
実行してみます。

実行

locale/japanese

locale/english


無事できました。

要点/注意点

  • ライブラリプロジェクトはProjectPropertiesのAndroidのis Libraryにチェックを入れる
  • ライブラリプロジェクトのAndroidManifest.xmlのアプリ名とアイコン名は削除する
  • ライブラリを使うプロジェクト側はProjectPropertiesのAndroidのライブラリに使用するライブラリを追加する
  • 追加した後はEclipseを再起動する*1
  • ライブラリのリソース名とアプリ側のリソース名は異なる物にした方が無難です

ちなみに

Androidライブラリを追加したあとのプロジェクトはいままでにはない面白い形になってますね

R.javaが二つあったり、ライブラリのjavaファイルが見えたり。
ちなみにここUtil.javaを変更するとライブラリプロジェクトのUtil.javaも更新されたり。

とりあえず

とりあえずできたという形で書きました。
あとは何ができるとか、どこが注意点だとかは誰かがまとめてくれるんじゃないかなー?
特に注意点は多い気がします。

*1:何か更新する方法があれば教えてください