Hatena::ブログ(Diary)

明日の鍵

2010-09-10

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

引き続き外部ライブラリのすゝめ2です。

今回はAndroidの外部ライブラリの作り方です。

前回の後半でもAndroidSDKのAPIを使う外部ライブラリの作り方書きましたが

今回はリソースを使う外部ライブラリの作り方です。

完全に外部化するからには国際化なんかも済ませておきたいですね。

構成

  • AndroidApp
  • AndroidLib
    • ライブラリプロジェクト
  • AndroidAppはAndroidLibのクラスのメソッドを呼び出します
  • AndroidLibは自身に定義されている文字列リソースを返します
  • AndroidAppは受け取った文字列をToastで表示します。

簡単なアプリですねー。

AndroidLib

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

New Project

f:id:tomorrowkey:20100910232148p:image:w400

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

f:id:tomorrowkey:20100910232149p:image:w400

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

新しく作成します。

日本語の文字列リソースです。


<resources>
  <string name="greeting">こんにちわ 明日!</string>
</resources>
res/values/string.xml

helloという項目を削除して、greetingという文字列を足します。

日本語以外の文字列リソースです。


<resources>
  <string name="greeting">Hello Tomorrow!</string>
</resources>
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

f:id:tomorrowkey:20100910234314p:image:w400

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

f:id:tomorrowkey:20100910234315p:image:w400

Add... -> AndroidLib -> OK

でこんな感じになると思います。

ここまで終わったらAndroidLibのプロジェクトを参照ができているはずなんですが

リフレッシュしてもクリーンしてもAndroidAppからAndroidLibのクラスは参照できず…。

f:id:tomorrowkey:20100910234316p:image

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

f:id:tomorrowkey:20100910234317p:image

/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

f:id:tomorrowkey:20100911002810p:image

locale/english

f:id:tomorrowkey:20100910234319p:image

無事できました。

要点/注意点

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

ちなみに

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

f:id:tomorrowkey:20100910234320p:image

R.javaが二つあったり、ライブラリのjavaファイルが見えたり。

ちなみにここUtil.javaを変更するとライブラリプロジェクトのUtil.javaも更新されたり。

とりあえず

とりあえずできたという形で書きました。

あとは何ができるとか、どこが注意点だとかは誰かがまとめてくれるんじゃないかなー?

特に注意点は多い気がします。

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

2010-09-08

外部ライブラリのすゝめ

きっかけ

GoogleAppEngineとAndroidの開発をしていて、共通に使用するコードを外部ライブラリ化したかったんだけど

プロジェクトのプロパティから他のプロジェクトの参照という方法では

簡単にはjarファイルを任意の場所に置けない事が分かって*1

いろいろ試行錯誤してこれに落ち着きそうな感じです。

ant

antを使えばjavaコンパイルや、jarファイル作成などマクロみたいに組むことができるんで

antのbuild.xmlを書きました。

ディレクトリ構成
root
 src
 bin
 build.xml
 xxx.jar

Eclipseで作成する普通のJavaプロジェクトで、build.xmlはプロジェクトの直下に置きます。

jarファイルはプロジェクト直下にできます。

ソース
  • build.xml
<?xml version="1.0" encoding="utf-8" ?>
<project name="xxx" default="deploy">

  <property name="jarname" location="./xxx.jar" />
  <property name="src" location="./src" />
  <property name="bin" location="./bin" />

  <target name="compile">
    <delete dir="${bin}/*" />
    <javac srcdir="${src}" destdir="${bin}" />
  </target>

  <target name="build">
    <delete file="${jarname}" />
    <jar jarfile="${jarname}">
      <fileset dir="${src}" />
      <fileset dir="${bin}" />
    </jar>
  </target>

  <target name="deploy" depends="build">
    <copy file="${jarname}" todir="./../gae_project/war/WEB-INF/lib" />
    <copy file="${jarname}" todir="./../android_project/assets" />
  </target>
</project>
使い方

主に変更する点

  • projectエレメントのname属性
    • 別に必須じゃないから変更しなくてもいいんだけど、プロジェクト名を指定
  • property:jarnameのlocation
    • ./の後に、作成するjarファイルの名前に変更する
  • target:deployのcopyエレメント
    • todir属性の値を、jarファイルを配置するディレクトリパスに変更する。

当初はコンパイルも書いてたんですけど、eclipseさんが自動的にコンパイルしてくれるので

target:compileは使ってません。消しても構いません。

さらに

まだ手を抜くために、antの実行もショートカットで簡単にしてしまいます*2

  • プロジェクトで右クリック
  • Properties
  • Builders
  • Import...
  • Build.xmlを選択*3

これをやっておくとCommand+Bで(WindowsならCtrl+B?)勝手にコンパイルされて配置されます。

クリーンしたときも勝手にコンパイルされて配置されます。

プロジェクトを実行しようとしてもコンパイルされて配置されるかも。

androidの外部ライブラリを作る

androidSDKのAPIを使う外部ライブラリを作りたいなと思ったので、それも調べました。

ようはandroid.jarを参照ライブラリに追加すればいいですね。

とりあえずユーザライブラリにAndroid.jarを追加する

  • Eclipseの環境設定
  • java
  • Build Path
  • User Libraries
  • New...
  • 「Android 2.2」と入力
  • 「Android 2.2」を選択
  • Add JARs...
  • 「/Applications/android-sdk-mac_86/platforms/Android-8/android.jar」を選択*4

これはandroid 1.5からそれぞれのバージョンしておくといいかもしれませんね。

あとはライブラリプロジェクトの参照ライブラリに追加します。

  • プロジェクトで右クリック
  • Build Path
  • Add Libraries
  • User Library
  • 「Android 2.2」を選択

これでAndroidSDKのAPIを使ったライブラリを作ることができます。

最後に

ほぼ自己流でやってるんで、こういうところを改善した方がいいよ!ってあったら教えてください!

特にant歴は3時間くらいなんで、すげー怪しいです。

twitterでも!コメントででも!

*1:簡単な方法がありましたら教えてください。私のがんばりが消えてなくなります…

*2:毎回のビルド時間が長くなり、一長一短だったりするんで、導入はそれぞれで判断してください

*3:一度Antを手動で実行しないと表示されないかもしれません

*4:環境によって異なります

2009-10-07

eclipseのエラー対応

たまーに

eclipseのエラーがでて、実行しようにもエラーメッセージが表示されてどうしようもないときがある。

こういうメッセージ

f:id:tomorrowkey:20091007230430p:image

まず

とりあえずおもむろに再起動する

それでもダメなら

cleanコマンドというものがあるので、実行する。

eclipse.exeと同じフォルダにclean.batっていうバッチファイル作っておくと便利

clean.bat

.\eclipse.exe -clean

これでパーペキ*1

たいてい治る

今日のeclipseのエラー

androidのプロジェクトで実行するときに失敗するというエラーが発生

原因はデバイスがいつのまにかオフラインになってたから

気づかずにプロジェクトの作り直しまでしてしまったorz

*1:パーフェクト完璧