smallgeek

Swing god gun, I need it low demon

Mono for Android と F#

この記事は F# Advent Calendar 2012 の 8回目です。

はじめるまえに

@さんのNaturalSpec 実践入門 、@さんのNaturalSpecを使ってC#のテストコードを書いてみた。で拙訳のチュートリアルを紹介していただき、ありがとうございました。折角紹介していただいたのに、NaturalSpec に関連した内容ではないのですが、NaturalSpec 関連の翻訳記事を暖めているところなので、近いうちにリリースしたいと思っています。 テストコードとヘルパー関数のギャップについては、ヘルパー部分が大きくなってきたら、別のモジュールに分割したほうが見通しはよくなるのかな、と思っています。分割するほどではなければ、F# Outlining を使って隠すとか(解決していない)。

はじめに

日々、F# の情報を集めようとアンテナを立てている方はご存じだと思いますが、The F# Software Foundation というページがあります。まだ新しいページではありますが、F# のニュースやコミュニティへのリンクがまとめられており、F# 関連の情報を収集するのに一役買っています。我らが F# User Group - Japan へのリンクもあるため、海外の F#er に日本人 F#er の活躍が伝わると嬉しいですね。

さて、そんな The F# Software Foundation の中に気になるリンクがありました。「F# on Android and iOS」……これは! リンク先を調べてみると、Android と iOS で F# を使えそうな雰囲気の漂う、中途半端な説明が。iOS の場合は WebSharper を使用し、HTML5 に変換したものを使う、と。他のクロスプラットフォーム SDK とやることは同じです。Android の場合は Mono for Android を使う……だと……! Mono for Android で食べている俺歓喜。ということで、Mono for Android と F# で本当に Android アプリケーションを開発できるのか調べてみることにしました。今年の F# Advent Calendar ってテーマが実用では? と思われるかもしれませんが、非常に実用だと思います。俺に。

環境を用意する

Mono for Android には VisualStudio 版と MonoDevelop 版がありますが、今回は VisualStudio で検証してみます。最新の Mono for Android SDK では VisualStudio 2010 と 2012 に対応しています。インストールは簡単で、JavaAndroid SDK などの必須ライブラリは、Mono for Android のインストーラーを実行するだけで勝手に準備してくれます。

新規ソリューションを作成し、Mono for Android 用のプロジェクトと F# ライブラリプロジェクトを追加します。

ソリューション エクスプローラ

まずはエミュレータで動作させることを目標とします。F# ライブラリプロジェクトを作成したときに合わせて作成される Library1.fs を流用して、Android アプリケーション側から F# ライブラリを使用してみます。F# ライブラリプロジェクトを参照し、ボタンのテキストに Class1 の X が表示されるようにコードを変更します。

この状態でデバッグ実行しようとすると、以下のエラーが表示されます。

エラー一覧

FSharp.Core が見つからないためビルドに失敗しているようです。ここで、Android アプリケーションのプロジェクトの参照に FSharp.Core を追加します。ここで追加しなければならないのは、VisualStudio の FSharp.Core ではなく、オープンソース版の FSharp.Core です。Windows の場合は、fsharp / lib / bootstrap / 4.0 の FSharp.Core をそのまま使うか、自分でビルドしたものを指定します。追加が終わったら、「ローカルにコピー」を true にしておきます。

エミュレータで動かす

この状態でデバッグ実行すると、Android のデバイス選択画面が表示されるので、デプロイ先を選択します。必須コンポーネントなどの配置があるため、少し時間がかかりますが、しばらく待つとエミュレータへのデプロイが完了します。

デプロイ

おお、デプロイできてしまった……ということで、ボタンをクリックしてみましょう。

クリック

ボタンのテキストが変更されました。Android アプリケーションから F# ライブラリを呼び出せていますね。

もっと洗練された方法

上記の方法で Android 上で F# のコードを動作させることはできていますが、警告が表示されてしまっています。

けいこく!

これは Windows Phone の開発で Silverright と XNA を同時に使うときに表示される警告と同一なので、仕方ないかな、と思っていたのですが、今年の Advent Calendar が始まってすぐ、こんなツイートを見かけました。

お、おう……。このタイミングでまさかの、でしたが、折角なのでソリューションを解析させてもらうことにしました。

TargetFrameworkVersion

まず、プロジェクトを見てみます。TargetFrameworkVersion が v2.2 になっていました。これはどうやら、.NET Framework のバージョンではなく、Android のバージョンを指定しているようです。参考までに、Android 2.2 は Froyo になります。このバージョンが Android アプリケーションのプロジェクトと同じものになっていました。

fsproj のインポート宣言

標準の F# Project では、下記のようにインポートが宣言されています。 次に、fsharp_droid のプロジェクトでは、標準とは異なったターゲットのインポートが宣言されています。

targetsファイル

targets ファイルはビルドに使用されるプロジェクトがまとめて定義されており、これをインポートすることで簡単にビルド構成を切り替えることができます。fsharp_droid の MonoDroid.FSharp.targets には、F# 用の targets ファイルのインポートと Mono 共通の targets ファイルのインポートが宣言されています。MonoDroid.FSharp.targets を Mono 用の targets ファイルが格納されているフォルダにコピーします。私の環境では "C:\Program Files (x86)\MSBuild\Novell" 以下になります。 targets ファイルをコピーし、TargetFrameworkVersion、インポート宣言を書き換えてプロジェクトを再読み込みするとエラーが表示されました。

インポートエラー

F# 用の targets ファイルの参照先が異なっていたため、MonoDroid.FSharp.targets ファイルを書き換えます。 再度プロジェクトを読み込むと、今度はエラーが表示されなくなり、ビルドできるように。警告も表示されなくなりました。すばらしい。

タートルグラフィックス

もう少し複雑なアプリケーションを作ってみます。#FsAdventJp のつぶやきを表示するアプリケーションにしようかと思いましたが、上で紹介したサンプルも Twitter 関連なので、被るのは避けます。いつだったか、コッホ曲線を描いてみると言った記憶があるので、それを作ってみることにしました。

亀です。

亀を作って動かしています。C# から呼び出す関数に CompiledNameAttribute を設定してみました。

Activity では View を設定するだけです。

カスタム View をタッチするたびに、コッホ曲線の次数を増やしています。とはいえ描画リソースが十分ではないので、次数の上限を適当に決めています。こういうのは OpenGL を使うべきなのでしょうか。

動かしてみる

1次 2次 3次

動作が確認できました。 無理にイミュータブルにしているのが災いしているのか、再帰の計算量が多すぎるのか、次数が増えると非常に遅いです。描画系プログラミングは難しいですね。

まとめ

想像していたよりも簡単に F# を使った Android アプリケーションを作成することができました。個人でライセンスを保有していないため、実機での確認はとれていません。また、マーケットの審査に通るかどうかも不明です。ちなみに、Mono for Android を使って作成された Android アプリケーションは全体の 1% 程度だそうです。ライセンスは決して安くありませんが、Visual StudioC# と F# を使って Android アプリケーションを開発できる、というメリットは魅力的です。もし Android アプリケーションを仕事で開発することになったら、ライセンス取得を申請してはいかがでしょうか。 最近、「Mono プログラミング」という書籍がアスキーから出版されました。日本語で書かれた稀少な資料であり、内容も素晴らしくわかりやすいです。Android の本としても良書なので、気になったら手に取ってみてください。

Monoプログラミング .NET/C#とMono for AndroidによるAndroidアプリケーション開発

Monoプログラミング .NET/C#とMono for AndroidによるAndroidアプリケーション開発

MonoTouch 版も翻訳されないかなー。

おわりに

今や Mono のおかげでプラットフォームを選ばずに F# でプログラミングができる時代が来ているといっても過言ではありません。ひょっとしたら、Mono ベースの PlayStation Mobile SDK でも F# ライブラリを呼び出せるのではないか、などと想像してしまいます。 とはいえ、まだまだ C# からの呼び出し、という形から脱却はできていないため、C# から F# ライブラリを使う方法や、C# からでも使いやすい F# のライブラリを作成するテクニックを身に着けておく必要があります。@ さんのC# から使いやすい F# コードの書き方や @ さんのライブラリを作ってみて感じたF#の良いところや悩みどころが非常に力になってくれると思います。

広告を非表示にする