ARM版AndroidのためのPharoアプリケーションの構築方法

あまり知られていないかもしれないが、Android上でPharo Smalltalkを動かすことができる。実際にPharoで作られたDrGeoというアプリケーションがGoogle Playで配布されているくらいだ。
以下では、Android上で動くPharoアプリケーションをどのように作るかについてまとめる。
情報源としては、squeakvm-tabletを参考にした。
なお、上記サイトではCogDroidとPharoDroidの2つのVMが利用できると書かれているが、後者は現時点でダウンロードできないため、前者のCogDroidを用いた作成方法について説明する。また、一般的にARMアーキテクチャのデバイスを用いることが多いと思われるのでARMに絞った話にしてあるのと、私自身はMac上で開発を行っているので、Macでの方法であることを予め断っておく。

用意するもの

以下をあらかじめダウンロードする。ダウンロード先はとりあえず ~/Downloads とする。

  1. Oracle JDK より、jdk-7u45-macosx-x64.dmgをダウンロード
  2. Apache ANT より、apache-ant-1.9.2-bin.zipをダウンロード
  3. Android SDK より、android-sdk_r22.3-macosx.zipをダウンロード
  4. Pre-built native Cog VM for the ARM architecture
  5. A template for building bundled and branded versions of Cog VM

Android開発環境のセットアップ

以下のようにダウンロードしたファイルをインストール・展開する。

  • jdk-7u45-macosx-x64.dmgを展開してインストールする。
  • apache-ant-1.9.2-bin.zipを適当なフォルダ(例えばユーザーのホームディレクトリ)に展開する。
  • android-sdk_r22.3-macosx.zipを上と同じフォルダに展開する。

この時点で以下のようなフォルダができているはずである。

apache-ant-1.9.2/
android-sdk-macosx/

各種ツールが利用できるように、~/.bash_profileを作成して以下を加える。(ユーザー名がxyzだと仮定している)

PATH=$PATH:/Users/xyz/apache-ant-1.9.2/bin:'/Users/xyz/android-sdk-macosx/tools'

ターミナルを起動して以下を実行し、Android SDKのコンポーネントをダウンロードする。

android update sdk -u

Pharoイメージの作成

PC上で適当なイメージでPharoを起動し、設定を行う。参考にしたサイトでは1.4ベースだったので、この記事では1.4のイメージを利用している。
Pharoを起動した後で、ソースファイルやチェンジファイルへのアクセスをさせないための設定を行う。適当にWorkspaceを開き、以下をDo itする。

SmalltalkImage checkSourcesFileAvailability: false.
SmalltalkImage checkChangesFileAvailability: false.

その後、適当な名前でイメージを保存する。(以下の例ではandroid.imageで保存したものとする)

ビルドに必要な情報の決定

  • アプリケーションのドメイン名を決める。とりあえず以下の例では、testapk.xxx.yyyとする。
  • アクティビティ名を決める。以下の例では、Mainとする。
  • APKのビルド名を決める。通常は”アクティビティ名-アーキテクチャ名”とするので、以下の例では、Main-armとする。

ビルド環境の準備

ターミナルを起動して、適当なフォルダを作成する。

mkdir testapk

そのフォルダにmakevm.zipを展開する。

cd testapk
unzip -x ~/Downloads/makevm.zip

makevmというフォルダができるので、そのフォルダに移動する。

cd makevm

そのフォルダに、nativeVM-arm.zipを展開する。

unzip -x ~/Downloads/nativeVM-arm.zip

(展開後にはprojectというフォルダができる)
※以後、ビルド終了まで makevm フォルダ内で作業していく。
以下のコマンドを実行する。

android update project -p . -t android-4 -l ./project

このコマンドの実行により、project.propertiesファイルの内容が更新されるが、元々記述されていた内容に問題があるため、以後のビルドでエラーが生じる。最終行のあたりは以下のようになっていなければならない。

# Project target.
target=android-4
android.library.reference.1=./project

アクティビティのJavaソースを置くためのディレクトリを作成する。アプリケーションのドメイン名がtestapk.xxx.yyyならば、以下のようなコマンドを入力する。

mkdir -p src/testapk/xxx/yyy

上のフォルダに以下の内容のJavaソースファイル(src/testapk/xxx/yyy/Main.java)を作成する。Mainは以前に決定したアクティビティ名である。Javaプログラム中のドメイン名やアクティビティ名は適宜変更する。

package testapk.xxx.yyy;
import org.golubovsky.cogstack.CogActivity;
public class Main extends CogActivity {
}

assetsフォルダの準備

assetsフォルダにimageフォルダを作成する。

mkdir -p assets/image

以前に保存したPharoのイメージを1Mバイトごとに分割する。

split -b 1m (イメージを保存したパス)/android.image assets/image/android.

分割すると、android.aaからandroid.atあたりまでの複数のファイルが生成される。
assetsフォルダにzippedフォルダを作成する。

mkdir -p assets/zipped

先ほど分割したファイルを(ディレクトリ名は付けずに)圧縮して適当なファイル名で保存する。(以下の例ではFFF.zipとする)

zip -j assets/zipped/FFF.zip assets/image/*

リソースの準備

AndroidManifest.xmlファイルを開き、以下のように修正する。(ダブルクオート記号も入力する)

  • @@PACKAGE@@ を “testapk.xxx.yyy” に置き換える。
  • @@ACTIVITY@@ を “Main” に置き換える。

build.xmlファイルを開き、以下のように修正する。(ダブルクオート記号も入力する)

  • @@BUILD@@ を “Main-arm” に置き換える

res/values/strings.xmlファイルを開き、以下のように修正する。

  • @@BUILD@@ を Main に置き換える

その他の作業

参考にしたサイトではうまくビルドできなかった。原因は、project/local.properties ファイルの中で設定している sdk.dirという変数の設定がまずいからで、以下のようにandroid update projectで生成されたファイルで上書きコピーすることで対処する。

cp local.properties ./project/

ビルド

以下のコマンドによりビルドする。

ant clean && ant debug

ビルドが成功したらandroid端末に転送して実行する。

イメージを変更してリビルドする

基本的に「assetsフォルダの準備」と「ビルド」を行えば良い。
以下のようなコマンドを実行するスクリプトでも書いておけばOK。

rm assets/image/*
split -b 1m (イメージを保存したパス)//android.image assets/image/android.
rm assets/zipped/FFF.zip
zip -j assets/zipped/FFF.zip assets/image/android.*
ant clean && ant debug
cp bin/Main-arm-debug.apk ~/Dropbox

その他

ポートレイトモードに変更する

上記のビルドではランドスケープモード(横長画面)でアプリが起動する。ポートレイトモードにするには、AndroidManifest.xmlを書き換えれば良い。

android:screenOrientation="landscape"

android:screenOrientation="portrait"

のようにすればポートレイトモードになる。

Android-Baseパッケージの導入

PharoからAndroidの機能にアクセスするためのパッケージを導入するには、Pharoイメージを開いて以下を実行する。

Gofer new
  squeakfoundation: 'VMMaker';
  package: 'Android-Base' constraint: [ :v | v author = 'golubovsky' ];
  load.

ただし、この状態ではPC上でSystem-Settingsでもprimitiveエラーが発生するため、Androidクラスの以下のクラスメソッドを修正する。

getVMTimerInterval
	"get VM idle timer interval"
	
	"self primitiveFailed.".
	^ 100

要はprimitiveFailedを起こさずにダミー値(100)を返すだけ。

トーストの表示

Toastを表示するには、以下の式を実行すれば良い。

Android briefMessage: 'test'.

文字の読み上げ

文字列を読み上げるには、以下の式を実行すれば良い。

Android speak: 'hello'.

その他クリップボードへのアクセスなども行えるようだ。