Xamarin.Android SDK解説 @技術書典 & @YAP(achimon)C Asia Hachioji etc.

これからしばらくの間、アジアでXamarin.Android SDKを紹介する活動が(わたしとしては)多くなりそうです。

まず、6/25(土)の技術書典で新しく発行される、TechBoosterの "AZ異本 grimoire of android" にひとつ寄稿しました(Xamarinで書けという(圧)がかかったともいう)。

techbooster.github.io

表紙のヤバさがヤバい。

5月に書いていたのですが、たいへん新しいネタで、書いていく傍らで変更がどんどん加えられ、動いているとされていたものが動いていないとか、いろいろチャレンジングな状況でした。でもまあ一応「この辺はあまりブレないだろう」というラインを中心に、基礎から内部的な解説まで、いろいろまとめています。

30ページくらいあって、同人誌の原稿としてはけっこう長々と書いたと思います。ただ、これでもだいぶ書くべきを端折っているんですよね…(力尽きて)。本当ならXamarin.Android徹底解説という題にするつもりだったのですが、全然徹底しなかったので、そこは外しました…

ちなみに、わたし技術書典のスタッフとしても動いていて、当日も現場にいる予定なので、ぜひ遊びに来てやってください。

techbookfest.org

おまけですが、6/9に、台北のFLOSSのグループH4で、技術書典や(原稿書きに使っている)Re:VIEWがどういうものなのか、という紹介をしてきたので、これもついでに上げておきます。(ざっくり10分程度のトークです)

speakerdeck.com

それから、その翌週の7/2(土)に、今度はYAP(achimon)C Asia Hachioji in Shinagawaという、どこなのかよくわからないイベントで、そのXamarin.Android SDKの解説セッションをやります。

yapcasia8oji-2016mid.hachiojipm.org

YAPC Asiaの後継イベントだけど、今度はごく少人数(というか基本的に1人?)でイベントを回すそうで、なかなか大変そうなところですが、会場に品川MS神社を借りてMS信者のおまいらがおまいりできるそうですので、興味がありましたらぜひ聞きに来てください。

本当は↑の執筆内容をもとに、念入りに話したいところではあるのですが、30分だけなので、いろいろ簡素な(でも平易ではない)内容になると思います。できればデモも動かしたいのですが、SDK本体の完成度次第と言ったところでしょうか(!)

最後に、8/27に、Microsoft台湾のコミュニティマネージャの人に相談されて、あちらのMVP Summitのようなもので、同じくXamarin.Android SDKの話をしてくることになっているのですが、これは内容的にはYAP*Cとほぼ同じにしようと思っています(時間は40分あるのですが、英語になるので密度は多分下げざるを得ないでしょう)。これも興味がありましたらぜひ来てください(台北ですが)。

JXUG#13 rejected meetup

#JXUG13 の参加申込み状況がえらいことになってますね。

jxug.connpass.com

参加したいけど出来ない感じの皆さんは残念ですね。

せっかく興味がある人が多い「ように見える」のに何もしないのはちょっともったいないので、前日の公開ですが、参加したかった皆さんのうち、Xamarinに興味がある方がいたら、適当に来てもらえれば相談などに乗る集まりをやろうと思います。個人的には以下のような目的だと面白いかもしれないと思いますが、目的を特定するつもりはありません(とりあえず、どれもJXUGではやらなそうなことです)

  • (xamarin-android、xamarin-macios、Xamarin.Forms)をビルド/ハックしてみる
  • Xamarin Workbooksで遊んでみる
  • Xamarin Forms Previewerで遊んでみる

場所は、わたしが上記の集まりに冒頭だけ参加しないといけないこともあるので、会場であるMicrosoft品川オフィス(いわゆるSGT)の2階にある cafe de crieあたりがいいかと思っています。もしいっぱいだったら周辺のカフェのどこかにします。(Twitter/@atsushieno でお知らせします) 誰も来なければ1人でもくもく作業していると思います。目印にこいつを置いておくので、適当に探して下さい。

時間も、適当ですが、上記の都合で、13:30スタートくらいだといいかなと思っています。

注意点ですが、Xamarin platformsはビルド時に大量のダウンロードを必要とするものです。自宅等で必要なセットアップを済ませてから来て下さい。

  • Xamarin Workbooks、Xamarin Forms Previewerを使うには、alpha previewが必要になります。
  • xamarin-android:
    • githubからxamarin-androidを --recursive でcloneしておく (特に、monoのチェックアウトが必要になるので、時間がかかる)
    • make prepareAndroid SDK / NDKのダウンロードをすませておく(現状ローカルにあっても使われません)
  • xamarin-macios:
    • githubからxamarin-androidを --recursive でcloneしておく(fsharpやllvmが必要になる)
    • Xcode 7.3以降が必要になるので、アップデートしておく(4GBくらいある)
  • Xamarin.Forms:
    • 一度コードをチェックアウトした後ビルドを行っておきましょう。中でXamarin.Androidコンポーネントを参照している部分があって、それら は内部的にAndroid SDKのサイトから依存関係のパッケージをダウンロードします。これがけっこう待たされるはずです。
    • フルビルドにはVisual Studio 2015が必要ということになっています(WP/UWPなどWindowsにしか無いものがあるため)。また、VS2015の追加アドインが必要になるようなので、README.mdをチェックして追加しておきましょう。

何か注意事項を思いついたら追記していきます。

オープンソース化されたXamarin.Androidの概要

追記: この辺の詳細はEssential Xamarin -Yin/陰-で一章使ってまとめてあるので、興味のある方はどうぞ。

何がオープンソース化されたのか

Xamarin Evolve 2016で、以下のリポジトリがMITライセンスで公開されました。

XamarinComponentsは、どちらかといえば(以前からある)pluginsの内容を吸収した、他リポジトリにリンクする、ポータルのようなかたちになっています。

今回オープンソース化されたのは、Xamarin platform SDKという部分で、これは一言で言えば「スタンドアローンで実行可能なリリースビルドのアプリケーションをビルドできる環境」になります。ビルドして実行するコードは提供するよ、それ以上の開発環境は提供しないよ、ということですね。Xamarin Studioはオープンソースになっていません(言うまでもないですがMonoDevelopは昔からオープンソースです)。アプリケーションをデバッグ実行したい場合は、相変わらずプロプラエタリのXamarin StudioかVisual Studioを使う、ということになります(ちとがっかり)。

これに伴って、Xamarin.iOSもXamarin.AndroidもXamarin.Formsも、大幅なリポジトリの再構成を余儀なくされており、またプロプラエタリコードの切り離し作業もおこなわれているので、率直に言えば開発者もまだ何が起こっているのかよくわからない状態です。ビルドも公式にはMacしかサポートされておらず、他のメンバーがせっせと壊したLinuxビルドを試行錯誤して直す作業をわたしがやったりしていました(というか今でもしている感じですね)。

ともあれ、今公開されてあるソースは、昔からあるやつのコードとは多少違うものだ、ということです。

そんなわけで、ソースが公開されたので、今回はこれまで詳しく書いていなかったXamarin.Androidの細かい部品について、ちまちまと書いていこうと思います。あんまり読みやすくまとめようという感じではなく、思いついたことを書き並べている感じです。

xamarin-androidの使い方

(この1行は後で消しますが)現状ではビルドされるファイルが不足していて、動かせる環境にないのですが、それでは目的が達成できていないので、今後数日のうちに修正されていくと思います。

Xamarin.Android SDKを使うには、コンソールからプロジェクトのcsprojをビルドするしかありません。

xamarin-androidリポジトリをチェックアウトすると、tools/scripts/xabuild というスクリプトがあり、これが必要な環境変数などをセットアップしつつxbuildを呼び出すように作られています。xbuildの代わりにこれを使うと良いです。(もちろん、無償化公表前のXamarin.Androidとは異なり、コンソールからビルドするのにProfessionalライセンスを必要とするようなことは、もはやありません。)

基本的には、MSBuildタスクを含むXamarin.Android.Build.Tasks.dllが、xbuildがMSBuild extension DLLを解決するパス(MSBuildExtensionPaths)に存在していれば、あとはXamarin.Androidのプロジェクトをビルドするために必要なXamarin.Android.{CSharp|FSharp}.targetsファイルがそのDLLの中に含まれるEmbeddedResourceとして解決されて、Xamarin.Android固有のタスク(BuildApkなど)を処理できるようになるはずです。

最新Xamarin.Androidの構成要素

monoランタイム

monoランタイムはxamarin-androidのgit submoduleとしてチェックアウトすることになります。

Xamarin.Androidは内部的にNDKでビルドしたmonoランタイムを使用するため、アーキテクチャ依存のネイティブライブラリ libmonosgen-2.0.so を含むことになるわけですが、公表時点でのxamarin-androidは、(あろうことか)デフォルトではarmeabiでのみビルドされます。まあこれはAndroid開発者のことを全く理解していないAndroidチームのやる気の無さの表れというよりは、OSS化の方針が決まってからEvolveまでほとんど時間がなかったからというのが大きいです。

xamarin-android内部では、この embedded mono runtime とAndroidプラットフォームを結びつける libmonodroid.so が使われています。xamarin-android自身は、monoランタイムとJNIのinteropを実現しているわけではなく、Androidアプリケーションのブートストラップの過程でmonoランタイムを初期化して利用可能にするためのコードなどが含まれています(Java.Interopモジュールの登場以前はこの辺は一体化していたのですが、Java.Interopの導入以降は、そういう構成になったようです)。

バインディング作成ツール

OSS版Xamarin.Androidには、Androidプロジェクトを新規作成するためのツールは含まれていません(!)が、IDEが無くても、バインディング ライブラリは、自前で作成することができます(!!)。

バインディング ライブラリは、Xamarin.Androidにおける機能の一部にすぎませんが、Mono.Android.dllはこのバインディング ライブラリをサポートする機能に基づいて作られているものであり、Xamarin.Androidの根幹を成す機能であると言えます。

バインディングDLLはどのように作成されているのでしょうか? 基本的な流れは、次のようになっています。

  • jar2xml: Javaライブラリ(jar)を解析して、API定義XMLを生成する
  • generator: API定義に対する修正を適用しながら、C#ソースを生成する
  • csc/mcs: C#ソースをビルドする

最初の部分では、膨大なAPI定義のXMLを生成します。C#コードをAPI定義とするXamarin.iOSとは全然違いますね。なぜこんな設計になっているかというと、これはもともと必要ないはずのツールだったのです。Android AOSPにはXMLベースのAPI定義が含まれており、Android 3.0がクローズドソースで公開されるようになるまでは、Xamarin.AndroidはAOSPのXML定義を解析するツール(generator.exe)のみを使用していました。それがクローズドソースのandroid.jarが登場するようになり、このままでは対応できない状態がいつまで続くか分からなかったので、jarファイルを開いて解析できるツールが必要になった、というわけです。

また、この頃からAndroid supportライブラリなどが登場し、外部ライブラリのAPIを簡単に使えるようにするための汎用的な仕組みが求められてきていました。そのため、それまでandroid.jarだけを相手にしていれば良かっただけのバインディング生成ツールに、さまざまな修正を加えてそれなりに一般化することになりました。この時点で、たとえば、generatorはjarだけでなくDLLも解析しなければならなくなっています(APIの階層構造を把握するためには、全てのjarが必要になるわけですが、依存ライブラリのjarは無いかもしれないですし、そもそもバインドされていないかもしれませんし、DLL上では全く別の名前になっているかもしれません)。

既にそれまでの時点でgeneratorはかなり複雑化していたところに屋上屋を架すことになって、今は割と「誰も触りたくない」部品になっています。残念ながら今のところこれを書き直す計画はありません。

class-parse: 新しいAPI抽出ツール

実は、この最初の部分については、次回リリースから選択肢が増えます。この選択肢は、バインディング プロジェクト ファイル(.csproj。F#はバインディングライブラリの作成ではサポートされていません)にMSBuildプロパティAndroidClassParserで制御できます。そこには、次の値のいずれかを指定します。

  • jar2xml
  • class-parse

jar2xmlJavaのリフレクションとバイトコード操作ライブラリASMを使用して作成されていましたが、class-parseC#で実装されています。jar2xmlが抱えていた絶妙な問題として、Javaリフレクションによって取得されるAPIは、そのコードを実行しているJVMに束縛されてしまう、というものがあります(.NETのSystem.Reflection APIと同じような問題ですね)。Mono.Android.dllには、本来android.jarに無いはずのJava7のAPIへのバインディングが含まれている、というバグがあって、これを解決するのはjar2xmlでは根本的に無理があった(出来なくはないが設計が全く異なるものになる)、というわけです。IKVMのコードを使いまわしたり、javapの出力を利用してはどうか、といったアイディアがいくつか出てきましたが、最終的にC#で書かれたシンプルなバイトコードパーサーを作って終わりということになりました。

もっとも、class-parseが銀の弾丸となったわけでは全くありませんでした。jar2xmlに知らないうちに頼りきっていたわれわれが直面した問題は、バイトコード解析だけではきちんとしたクラス階層の処理ができない、ということです。たとえば、Javaではpublic型をnon-public型から派生できるわけですが、java.lang.reflectはそれをうまく隠してくれていたわけです。class-parseは愚直なパーサーで、その辺りを全く解決しませんでした。

class-parseの開発時は、jar2xmlの出力フォーマットとの互換性も全く気にしていなかったため(generator.exeも拡張してclass-parseフォーマットもサポートすればいい、程度に考えていました)、生成されたXMLに対してさらにMetadata.xmlなどによってAPI定義を修正しなければならないという問題もありました。

また、AOSP由来のXMLでは、派生クラスでオーバーライドされた実装メソッドなどの情報は含まれていませんが、class-parseは愚直なバイトコードパーサーなので、その辺の事情を全く考慮しません。つまりclass-parseの出力は情報の構成が変わってしまっているわけで、そのままgeneratorに渡したわれわれが目にしたのは、大量のコンパイルできないC#コードでした。

結局のところ、今まで通りgeneratorに仕事してもらうためには、class-parseの出力を変換して正常化しなければなりませんでした。以上のような問題をまとめて解決するために、新たにapi-xml-adjusterというツールが作成されました。これは、class-parseの情報をもとにクラスの階層構造を解決して適切な修正を加えつつ、API XMLの構造を変換する役割を分担します。

generator

generatorは以上のような過程を経て生成されたAPI定義XML (バインディング ライブラリ プロジェクトをビルドすると、obj/* 以下に、api.xmlというファイルが生成されるはずです)をもとに、指定されたMetadata API fixup(Metadata.xmlなど)を適用して、クラス階層構造を構築し、インターフェース メソッドなどを抽象クラスで適宜追加し、プロパティやイベントにメンバーを変換・追加して、最終的なDLLのソースを生成します。コードの生成はTextWriter.WriteLineで行っています。いちいちCodeDomなんて使っていません(CodeDomはResource.designer.cs/.fsの生成時に使っています)。

ここ数ヶ月の間に追加された地味な機能のひとつに、Android Annotationsのサポートがあって、たとえばRequirePermissionなどのアノテーションJavaソースに追加してビルドしてさらにきちんとaarにパッケージされたものについては、それを読み込んだ上で対応するattributeを追加するようにしたはずなのですが、肝心のandroid.jarに対応するAndroid SDKのplatform-tools/api/annotations.zip の内容が、いつまで経ってもLollipopの内容のままで止まっていて、たとえばandroid.media.midiAPIに対応するIntDefなどが追加されないままなので、Google仕事しろと思いながら日の目を見ない機能のひとつとなっています。

あとさらに細かすぎて伝わらない追加機能として、同じくAndroid SDKのplatform-tools/apiにある api-versions.xml を読み込んで、ApiSinceというattributeを生成するようにしたのですが、IDE側でこれに対応するメッセージが表示されているかどうかは未確認です(出るようにする、とは言っていました)。使っているAPIがminSdkVersionで指定したバージョンにに無く、コード上でバージョンチェックも通していないと、実行時エラーになってしまうので、簡単に回避できるようにはしたいですよね。

MSBuildタスク

Xamarin.AndroidMSBuildタスク…というより正確には一連のタスク群ですが…は、xbuildあるいはMSBuildでXamarin.Androidのプロジェクトをビルドするために必要なもので、Xamarin.Android.Build.Tasks.dllに含まれています。

このMSBuildタスク群の中には、Androidアプリケーションのプロジェクトで使われるAaptやBuildApkといったタスクの他、Binding projectのためのJarToXmlやBindingsGeneratorといったタスクも含まれています。

ただ、これまでの製品版と大きく異なる部分があって、fast deploymentなど、デバッグビルドのために存在していたタスクが、根こそぎプロプラエタリコードに持って行かれています(つまり、xamarin-androidには含まれていません)。やれやれですね。最新のプレビュー版にはInstant Runのcold swap相当のコードも実装してあるので、そこも公開されていると少し面白かったのですが。

ライブラリ

Mono.Android.dll

Mono.Android.dllは、複数のAndroidプラットフォームに対応する、やや特殊なバインディング ライブラリです。基本的に、サポートするAPI LevelごとにMono.Android.dllをビルドするのですが、それぞれのAPI Levelのandroid.jarの単純なバインディングを生成しているのではなく、それぞれのAPI Level以下のAPI定義をマージした上で、それに対するバインディングを生成しています。これは、Java言語のVMCLIでは、存在しないメソッドを解決するやり方が微妙に異なり、異なるプラットフォーム間でのandroid.jar(に対応するDalvikバイトコード)では生じない問題が、Mono.Android.dllでは生じることになるため、メソッドの定義を適宜前方互換にしてやるひつようがあるためである、と説明されています。

(その副作用で、いつまで経っても邪魔なOrg.Apache.Http*が消えない、といった問題を抱えています。)

以上のような理由などもあって、Mono.Android.dllのビルドは次のように、いくつかの点で特殊な構成になっています:

  • API定義XMLは、生成済みのものがリポジトリに含まれています。
    • API定義XMLは、それぞれのAPI Levelについて、class-parseとapi-xml-adjusterを使用して生成しますが、ビルド時には必要ありません(この辺りをハックしたい人や、新しいAPI Levelの登場時にそのサポートを追加したい人がやります)
  • Mono.Android.dllのビルドでは、まずapi-mergeが呼び出され、生成済みのAPI定義XMLがマージされ、その次にgeneratorがソースを生成し、最後にmcsがC#ソースをコンパイルします。
  • Mono.Android.dll用のメタデータXMLではなくCSVファイルになっています(!) これはXamarinのチーム内ではもともと使われていたフォーマットが、前述のような歴史的な理由で公開ツールとなった時に、仕様の不安定なCSVフォーマットは公開せずにXMLにするという決定が下されたためです。これはgenerator内部でXML形式に変換されて処理されます。

Mono.Android.dllのソースはgithub上の xamarin-android リポジトリにありますが、これは(名前から推測できる通り)Xamarin.Androidの(OSS版の)中心的なリポジトリです。Java.Interopやmonoをsubmoduleにしており、libmonodroidと呼ばれる、Androidアプリケーションのライフサイクル上で動作するmonoのホスティング環境を、Androidの各CPUアーキテクチャごとにビルドします。これには非常に時間がかかります。monoをひとつビルドするだけでも時間がかかるのに、それを(ランタイムだけとはいえ)アーキテクチャごとに行っているわけです。

5/4追記: ↑は現在は正確ではないかもしれません(libmonodroidがarmeabiのビルドしか行っていないため、多分こちらもarmeabiのみ)

xamarin-android リポジトリのソースは、大別して3つに分けられます。

  • ライブラリ (src/Mono.Android, src/Mono.Android.Export)
  • msbuildタスク
  • ビルドツール (ライブラリのソースを生成するツールなど)

Java.Interop.dll

Xamarin.Androidは、前回のstableリリースから、内部的な構成を大きく変えて、Mono.Android.dllの内部で、新しくJava.Interop.dllというライブラリを参照しています。ただし、公開APIの観点では、特に変更はありません。この新しいDLLは、Android APIバインディングを含まず、JNIを通じたJava APIの呼び出しを実現するために必要な機能だけを含むライブラリです。

Java.Interop.dllは、ほぼJNI呼び出し部分を最適化するために新規開発されたものであり(README.mdには「これはセカンドシステム症候群だ」と明言されています)、アプリケーション開発者が気にするべき部分は基本的にありません(もともと、このリポジトリは、メイン開発者が実験的な遊び場として使っていたという側面が大きいです)。

github上の Java.Interop リポジトリには、Java.Interop.dllと、これに基づくバインディングを作成するためのビルドツールの機能を実装するDLLがいくつか含まれています。現状、このリポジトリには、実際の製品で使われていない実験的なコードも数多く含まれているので、ここで全てを説明することはしません。

Java.Interopに含まれるソースは、大別して2つに分けられます。

  • ライブラリ。src/Java.Introp がその中心となる、Java.Introp.dllをビルドするためのプロジェクトです。
  • 公開ビルドツール用ライブラリ。Java APIバインディングを生成するためのツール(generator.exeなど)の機能を実装しているライブラリが、ここに含まれます。

この他に、ビルド時にしか使用しないツールなども含まれているのですが、重要性は低いので省略します(JNIEnvクラスの大量のメンバーを自動生成するツールなどがあります)。

Java.Interopは、開発者が何を思ったのかMSBuildの仕組みだけで全てビルドできるように複雑なビルドスクリプトをセットアップしたのですが、Windows上ではビルドしないわ、Linuxビルドも壊れているわ、Android SDKダウンロードまでスクリプト化したもののエラー トラッキングなどがまともに出来ないわ、カスタムSDKセットアップの柔軟性は微塵もないわで、端的に言ってこのビルドスクリプトは失敗作です。が現状それしかないので我慢するしか無い。

それはさておき、Java.Interop.dllがあると何が出来るかというと、たとえば、このコア部分だけを再利用したまま、全く別のAPIマッピング理論に基づくバインディングDLLを構築して使用することができます。当然ながら、そうすると過去の遺産は使えなくなるわけですが、support-v*ライブラリなどは自分でビルドすることもできるため、多くの人にとっては、あまり問題にならないでしょう。特にXamarinが提供してきたGoogleのライブラリに対するバインディングは、ソースが公開されることが期待されていますXamarinComponentsリポジトリでソースが公開されています。

(今のところ、XamarinでMono.Android.dllのAPIを抜本的に差し替える予定はありません。)

もちろん、Xamarin.AndroidAndroidアプリケーションを作るためのものであり、Androidアプリケーションは、Androidアプリケーションのライフサイクルに従ったものでなければなりません。既存のMono.Android.dllを使用しなくても、その根本に変わりはありません。

Xamarin.AndroidのN previewとJava8サポートについて

Google I/Oが近づいていますが、それに先立ってAndroid N previewが公開されていますね。既にpreview 2で、今後も5週間ごとにプレビューが出続けるというので、最新版Androidへの対応もだいぶやりやすくなったなという感じです。

そんなわけで、Xamarin.AndroidのMono.Android.dllも、OSS版xamarin-androidとXamarin.Androidの最新preview版は、最新のN preview 2まで対応しています。

Android N APIの最大の特徴は、Java8に対応したことですが、Xamarinユーザーにとっての恩恵はほぼ無いでしょう。

恩恵は無いのですが、Java8サポートは極めて難しい問題をもたらしました。インターフェースのデフォルトメソッドです。当初、N preview 1が登場した後、Mono.Android.dllはこれらについてもメソッドを生成していました。しかし、C#Javaとは異なり、デフォルトメソッドをサポートしません。当然ながら、インターフェースで定義されたメソッドは実装しなければならないことになります。Javaではこれは「やってもいいし、基本やらなくていい」ことなのに、C#になったとたん「やらなければならない」ことになるのは大変です。Java.Util.Iteratorなど、ごく基本的なインターフェースに、突如大量のメソッドが追加されて実装しなければならなくなったわけです。しかしインターフェースでAPIを定義しないと、誰も実装をオーバーライドできないことになります。

しばらく考えましたが、これはいくら何でもメソッドを追加するわけにはいかない、ということで、今のところ、デフォルトインターフェースメソッドは生成しないことにしました。通常のインターフェースメソッドでこういう「省略」を行うと、アプリケーション開発者がバインディングクラスの派生クラスを定義した時に生成するAndroid Callable Wrapper (ACW)が必要なインターフェースメソッドを生成せず、javacがコンパイルエラーを起こすことになるわけですが、インターフェースデフォルトメソッドの場合には問題になりません。

必要であれば、多少ややこしいコードを書く必要がありますが、手作業で追加することも一応可能です。

この辺は、OSS版xamarin-androidのrepoでRFC状態になっているので、何かしら意見があれば書いておいて下さい。

Java 8 Interface Binding · Issue #25 · xamarin/java.interop · GitHub

個人的には、まだどこにどう需要が出てくるかわからない現状で、中途半端なバインディング生成機能を実現したくない派です。現状ほぼメリットないし。

ちなみに、Android SDKでJava8が必要となるソースをコンパイルする際には、javacではなくjackという新しいGoogleコンパイラーを使用する必要がある(ということになっている)ことになっているのですが、

gfx.hatenablog.com

Xamarin.Androidが内部的に生成するコードはJava8の文法を使用しませんし、Java8のjavacをそのまま使っていても問題ないはずです。

JavaバイトコードをDalvikに変換するdx(dx.jar)には、--no-strictというオプションがあって、これを指定しないとJava8のバイトコードは拒絶されてしまうのですが、Xamarin.Androidでは内部的にこれを指定してdxを呼び出しています。

また、java8が問題になるのはproguard(およびそれを内部的に使用するmultidexのツールmainDexClasses)で、この古いツールはJava8に対応していないので、Xamarin.Androidではproguardの使用が指定されていたら、Java7にフォールバックします(実のところ、proguardの中身をいじって、参照されているデフォルトメソッドも全部スキャンするようにしてしまえば良いわけで、それほど対応が難しいとは思えないのですが、Googleはjackへの移行を促進するために政治的に非対応にしているんじゃないかと邪推しています)。

以上、インパクトがありそうでない、ちょっとしたXamarin.Android小ネタでした。

Xamarin Workbookの起源とインスタント実行の系譜

しばらく前、2月の半ば頃のことになりますが、MiguelがThe Evolution of Interactive C#というブログポストを投げていました。

The Evolution of Interactive C# - Miguel de Icaza

奇しくもわたしがDroidKaigi 2016でInstant Runについてのセッションを行う直前に公開されたもので、まあ幸い誰も気づかなかったと思いますが、完全にセッションのオチのネタバレだったんですね。 どうネタバレだったのかはスライドの最後の方を見てもらえれば分かると思いますが、

speakerdeck.com



最後に触れているContinuous Coding、けっこう新しいネタだったので、誰も知らなかったと思いますが、先のMiguelの投稿でも触れられているんですね。

(そういえば、このセッション資料、先日のGoogle Developers Summit TokyoでもGoogle Japanの人に紹介していただいたそうです。インスタント実行とは関係のない文脈だと思いますが、いずれにしろ役に立つネタで良かった^2)

さ て、先の投稿でWorkbookについて言及していることに気付きましたか? 実はシークレットでも何でもなかったんですね。まあ、せっかくなので、Miguelが書いたネタを日本語でなぞってみようと思います。

Xamarin Evolve 2014で発表されたXamarin Sketches、皆さん覚えているでしょうか?

atsushieno.hatenablog.com



Sketches はIDEのpane上に描画されたREPL環境で、XcodeのPlaygroundによく似ていますが(と言ってもそれを誰でも使えるかたちで実現した のはXamarinが先なんだよね、みたいな話は↑のエントリで説明してあります)、この時のcanvasは確かXamarin.Macがベースになって いて、Miguelはこれを「みんなが実際にやりたかったことは、単独のスケッチを実行することじゃなくて、アプリケーションを実際に動かしながら描画す ることだったから、あまり便利じゃなかった」と回想していますね。そして、それで作られたのがXamarin Inspectorだった、というわけです。

blog.xamarin.com


Inspector は、その名の通り、UI要素の内容をinspectするために作られたものですが(それ自体はTest Cloudの要素でもあるXamarin.UITestや、そもそもAndroid SDKにはhierarchy viewerなんかも同じですね)、その内容を動的に書き換える機能もREPLの統合によって実現しています。Inspectorが面白いのは、UI要素 をクエリする部分と描画する部分を切り分けていて、描画する部分は基本的にHTML Canvasでやっているんですね。

https://developer.xamarin.com/guides/cross-platform/inspector/Images/mac-3d-view-small.png



Inspectorはまだプレビューですが、基本的にこの辺りのプロジェクトは全て繋がっているわけです。

ところで、ハッカーの皆さんには割とよく知られていると思いますが、Jupyter Notebookというプロジェクトがありますよね。

Try Jupyter!


Jupyter Notebook、かつてIPython Notebookとして公開されていたプロジェクトですが(Miguelの先の投稿でIPythonって書いてあることに気付きました?)、まあ、要する に、これらは皆同じ「markdownの中に埋め込まれたREPL」の系譜です。Workbookの発想そのものは、特に新しいものじゃないんです。

Xamarin Workbook、面白いので、みんなこれを使ってドキュメントを書くといいと思います。と言いたいところなんですが、Workbookは Inspectorの一部で、Inspectorはオープンソースじゃないんですよね…まあ、コードが実行できなくても、サンプルコードフラグメントがド キュメントに含まれていて、それが実行可能だというのは有用なので、手元で動かせればいいという人はぜひ使ってみて下さい。

この Workbookも、Continuous Codingも、基盤として使用しているのはInspectorです。特にContinuous Codingはソースが公開されているので、使おうと思えば誰でも使えるということがみてとれるかと思います。けっこう夢がひろがりんぐだと思いませんか? (無理ですかそうですかそうですね。。)

アンカンファレンスやろう

Xamrin Evolveが再来週に迫ってきましたね。

https://evolve.xamarin.com/

参加される皆さんどうぞよろしくお願いします。

 

まあそんな人はほぼ皆無だと思うわけですが、日本ではde:codeの前夜祭のようなものがあって、de:code参加者でなくても参加できるそうなので*1、前回書いたようなゲリラ(非公認)ミートアップのようなものをここでやりましょう。*2

connpass.com

アンカンファレンスって何?

アンカンファレンスというのは、セッションのように誰かが1人だけ発表して他の人はそれを聞くだけ、みたいな退屈な時間ではなくて、誰かがトピックを持ち込んで、それについてみんなが会話に参加するかたちで作っていく、単なる雑談の場よりはもう少しオーガナイズされたミートアップのようなものです。

プロジェクターがあるのでスライドを見せながらしゃべることもできますが、1人でしゃべっているだけだと単なる短いセッションで終わってしまうので、それは用意しても手短に、あるいは画面を共有するに留めるのが良いでしょう。わたしは基本的にスライドみたいなものを用意するつもりはありません。(Webページをみんなで眺めることはあるかもしれませんが。) 質疑応答が活発であれば、それで終わるかもしれませんね。

まあ先着順のようなので、そもそもその場でアンカンファレンスにエントリーできるかどうかは当日にならないとわからないのですが、わたしがいることには変わりないので、何かしらの場が作れるだろうと思います。15分で終わらなかった話をテーブルの外で続けてもいいですしね。

*1:かく言うわたしもde:codeには参加登録していませんし

*2:すぐに人数がいっぱいになったらどうしようと思ってちょっと待っていたのですが、その懸念は必要なかったようですしね。

Xamarin is going to be open to Everyone

Microsoft Build 2016 2日目のキーノートで、MonoランタイムがMITライセンスに変更され、Xamarin Runtimeと称されるXamarinプラットフォームの部分がオープンソース化されることが発表されました。

blog.xamarin.com

今後数ヶ月、おそらくは来月のXamarin Evolveまでに、何かしらの成果が公開されるのでしょう。Buildから1ヶ月もしないうちにXamarinオンリーイベントとか、まあまさかもう動かせないしやるしかないって感じですね。ちなみに参加が危ぶまれていたわたしですが、何とか行けることになったので、現地に赴かれる酔狂な皆様もある意味ご安心下さい。(?)

(XamarinがVSに…云々は、ここではどうでもいい話なので、そういう話はそういう方面のコミュニティを眺めて下さい。)

monoランタイムがMITライセンスになると、Unity(3D)のような製品が、ライセンスを気にすること無く、既に組み込みLinux環境に最適化されたmonoを、改変ソースを公開せずに使用できるようになります。(ただし、Unityで使用されているmonoランタイムは、本家monoにかなり手を加えたものであり、かつかなり昔のバージョンをもとにしているはずなので、最新版のmonoにすんなりアップデートするということはないだろうと思います。) .NET Coreも既にクロスプラットフォームで動作しますし、.NET MicroFxという選択肢もありますが、いま.NET Coreを選ぶのは、長期的な計画でもなければかなりチャレンジャーであることは否めませんし、minimized runtimeやstable embedded APIを期待している人は、まだmonoを選んだほうが良いかもしれません。この辺は、それぞれの特性や自分の計画を踏まえて選ぶのが良いでしょう。

ランタイムがMITライセンスに変更になったのは、もちろんMonoチームがもはや組み込みライセンスビジネスで生きていく必要がなくなった(Microsoftエコシステムの一部として開発していく)ことから実現したものです。

そしてXamarinプラットフォームのOSS化。ついにこの日が来てくれた、という感じです(まだですけど)。

いずれはLinux環境でも利用可能になり、全てとは言わないまでもコア部分だけでもオープンソースの環境として公開し、アプリケーションが開発できるようになってほしい、と思っていましたが、とうとう実現しそうです。

公式ブログには、アプリケーションをビルドするために必要となるツールとライブラリ一式がOSS化される、とあります。もちろんMicrosoftは全てをオープンソースに捧げているわけではなく、Visual StudioなどのIDEに統合する部分を、引き続き製品の一部として(のみ)提供していくわけで(ちなみにXamarin Studio for Windowsは無くなります。もちろんMonoDevelopは引き続きOSSです)、その部分はクローズドソースで収益源になるようです(その辺はFAQを見てもらえればと思います)。

ソースを書いてアプリケーションをビルドするための、最小限の環境は提供するから、IDEに頼りきらない開発者は我が道を切り開いて歩いてくれ、ということです。面白い。受けて立とうじゃないか。われわれは.NET Framework SDK Toolsしか無いような環境でも生き延びてきたんだぜ。(って自分が中の人だったことを忘れるところだった…)

個人的にも、自作のライブラリなどをiOS/Androidで展開する時に、商用製品を買ってもらわないとcontributeしてもらえない事態には、忸怩たる思いがあったので、これで誇りをもって開発していくことができます。

オープンソースで.NET開発を推進してきたMonoが、Xamarinになってクローズドソースの製品を売り続けてきたのを、Microsoftが買収してオープンソースにして公開するというのは、歴史の皮肉とも言えますが、実に面白い展開になってきましたね。

面白いといえば、JetBrainsとUnity3DとRedHatが.NET Foundationにjoinするというニュースもなかなかのインパクトだと思います。Riderもプレビュー版が公開されたばかりなので、JetBrainsが、Javaで書かれたIDEに.NETをどう組み込んで統合していくか、見ものですね。わたしが彼らに大いに期待しているのは、.NET Core統合の実現です。RedHatLinux環境で.NET Coreの普及を促進していくための協業をどう展開していくかですね。Unityは、まあ言うまでもないでしょうけど、最適なランタイムを実現するための選択肢が広がって、近くない将来の見通しは良くなったのではないかと思います。

Build1日目のUbuntu組み込みの件も含めて、今回のBuildには面白いネタがたくさんありましたね。日本でも5月下旬のde:codeでいろいろ紹介されると期待しています。わたしは今のところ参加する予定はないのですが(どういう身分になっているのかすら何も決まっていないし!)、この辺に関心のある人が集まる日々になるので、何かしら集まって話せる機会を設けたいところですね。