libGDX的にも推奨していそうなIntel Multi-OS Engineについて。
https://github.com/libgdx/libgdx/wiki/Setting-up-your-Development-Environment-(Eclipse,-Intellij-IDEA,-NetBeans)
Intel Multi-OS Engineを使えばJava or Kotlinでクロスプラットフォームのアプリが作成可能とのこと。
前回のMobile Open JDK9の話に続き、調査してみようと思います。
AndroidもiOSにも対応、Mobile OpenJDK 9について
Intel Multi-OS Engineとは
Intel Multi-OS Engineはあの「インテル入ってる」でおなじみ?な
Intelが開発しているクロスプラットフォーム用のライブラリです。
OSSです(というのをIntelもアピールしています)。
https://multi-os-engine.org/
GitHubにorgもあります。
https://github.com/multi-os-engine
略すと"moe"なので"萌え"とかそういうの言う人にはCore2Duo投げつけましょう。
プラグインが提供されているIDE
Eclipse, IntelliJ IDEA, Android Studio。
おそらくIDEプラグインに過ぎないので、
Gradleビルドが出来るIDEであれば(IDEでなくても)利用可能だと思います。
Gradle推しっぽいですが、Mavenプラグインも準備しているようです。
https://github.com/multi-os-engine/moe-plugin-maven
開発環境の必要スペック
Mac
- macOS 10.11以上
- メモリ4 GB以上(8 GB以上オススメ)
- Apple Xcode 7.3以上
- Xcode Command Line Tools
- iOS 8 SDK以上
- Oracle JDK8以上
- Android Studio 2.1以上
- Android SDK API level 9以上
Win
- Windows 7 OS x64以上
- メモリ4 GB以上(8 GB以上オススメ)
- Oracle JDK8以上
- Android Studio 2.1以上
- Android SDK API level 9以上
- Windows用Apple iTunesアプリ
- iOSを試す場合はSSHでMac端末にアクセス
仕組み
Multi-OS EngineのランタイムはAndroidのランタイムであるARTがベースになっています。
ARTはiOSでもパフォーマンスを出すフィーチャーをいくつか持っています。
- AOT(Ahead-of-time)コンパイルによるパフォーマンス改善
- Androidで利用可能なライブラリ群の利用により、クロスプラットフォームアプリ開発を簡単に
- GCでメモリ管理をエンハンス可能
https://doc.multi-os-engine.org/multi-os-engine/2_Introduction/Introduction.htmlより引用
ということで、Androidで書いたアプリがそのままiOS用のアプリケーションとしてMOEプラグインによってビルド可能です。
下図はAndroid Studioを例に出していますが前述の通り、IDEは問いません。Gradleプラグインが用意されていますので、GradleプロジェクトであればIDEは関係無いですからね。
https://doc.multi-os-engine.org/multi-os-engine/2_Introduction/Introduction.htmlより引用
iOSのUIデザインはどうするか
UI部分は通常のiOS開発と同じようにXcodeなどでつくる必要があります。
ただし、libGDXなどクロスプラットフォーム対応のゲームエンジン上であればそこまでUI差分はないですが。各プラットフォームのデザインガイドを意識する必要のあるアプリ開発であれば、UI作成はプラットフォームごとに作成が必要そうですね。
Nat4JというライブラリでネイティブとJavaのブリッジをしてUIをバインドするみたいです。
Nat/J: Interoperability with Native Code
試す前の事前準備
事前準備として、僕の場合はIntelliJ IDEAを利用しているため、moeのIDEプラグインを導入しました。
Prefrences>Plugin>Browse Repositories...>「multi-os」と検索で出てきます。
Getting Started(Java)
サンプルコードがGitHub上にアップロードされています。
サンプルコードを落としてきます。
git clone https://github.com/multi-os-engine/moe-samples-java.git
中身を探る
中身を見てみます
$ ls
Calculator LocalizedString SimpleChart
CurrencyConverter MuseumMap SpeakHere
FastJNI NOTICE.txt Taxi
HelloMaven Planets TheElements
InAppPurchase README.md TicTacToe
いくつかサンプルアプリが入っているんですね。とういか、README.mdを見ればそのあたり書いてあります。
とりあえず、今回はCalculatorを動かしてみます。
Calculatorアプリの構成はこんな感じです。
yank-no-MacBook-Pro:Calculator yy_yank$ tree
.
├── android
│ ├── build.gradle
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── org
│ │ └── moe
│ │ └── samples
│ │ └── calculator
│ │ └── android
│ │ └── CalcActivity.java
│ └── res
│ ├── layout
│ │ └── calc_activity.xml
│ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ ├── mipmap-ldpi
│ │ └── ic_launcher.png
│ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-v21
│ └── styles.xml
├── build.gradle
├── common
│ ├── build.gradle
│ └── src
│ └── main
│ └── java
│ └── org
│ └── moe
│ └── samples
│ └── calculator
│ └── common
│ ├── CalcOperations.java
│ ├── CalcOpsTypes.java
│ └── CalculatorAdapter.java
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── ios
│ ├── build.gradle
│ ├── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── moe
│ │ └── samples
│ │ └── calculator
│ │ └── ios
│ │ ├── Main.java
│ │ └── ui
│ │ └── AppViewController.java
│ └── xcode
│ ├── ios
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Icon-60@2x-1.png
│ │ │ │ ├── Icon-60@2x-2.png
│ │ │ │ ├── Icon-60@2x.png
│ │ │ │ ├── Icon-76-1.png
│ │ │ │ ├── Icon-76-10.png
│ │ │ │ ├── Icon-76-11.png
│ │ │ │ ├── Icon-76-12.png
│ │ │ │ ├── Icon-76-2.png
│ │ │ │ ├── Icon-76-3.png
│ │ │ │ ├── Icon-76-4.png
│ │ │ │ ├── Icon-76-5.png
│ │ │ │ ├── Icon-76-6.png
│ │ │ │ ├── Icon-76-7.png
│ │ │ │ ├── Icon-76-8.png
│ │ │ │ ├── Icon-76-9.png
│ │ │ │ ├── Icon-76.png
│ │ │ │ ├── Icon-76@2x-1.png
│ │ │ │ ├── Icon-76@2x-2.png
│ │ │ │ ├── Icon-76@2x.png
│ │ │ │ └── Icon-83.5@2x.png
│ │ │ ├── Contents.json
│ │ │ └── MOELogo.imageset
│ │ │ ├── Contents.json
│ │ │ └── moe-logo-200x200.png
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── main.cpp
│ ├── ios-Test
│ │ ├── Info.plist
│ │ └── main.cpp
│ └── ios.xcodeproj
│ └── project.pbxproj
└── settings.gradle
47 directories, 57 files
androidディレクトリ=androidプラットフォーム固有、iosディレクトリ=iosプラットフォーム固有、common=共通部分でしょうね。
それぞれがGradleのmoduleとして扱われています。
Androidの方はCalcActivity.java、iOSの方はAppViewController.javaというクラスが用意されています。
これがそれぞれのUI部分です。Android側に関しては特筆することはありません。
フツーにAndroidで開発している時同じです。iOSの方は色々特徴があります。
クラスヘッダだけみても結構特徴があります
@org.moe.natj.general.ann.Runtime(ObjCRuntime.class)
@ObjCClassName("AppViewController")
@RegisterOnStartup
public class AppViewController extends UIViewController {
- ObjCRuntimeアノテーションでランタイムをObjective-C指定している
- ObjCClassNameアノテーションでObjective-Cのクラス名を指定している
- RegisterOnStartupアノテーションでiOSランタイムへの登録タイミングを指定している
- UIViewController.javaを継承している
UIViewControllerはiOSが提供するAPIで、それをwrapしたものをMulti-OS Engine側で用意していたものです。
UIViewControllerの詳細はAppleのAPIリファレンス参照のこと。
UIViewController - API Reference
ソースも軽く見てみて欲しいのですが、UIButton、UIColor、UILabelなどもMulti-OS Engine側で用意しているため普通に利用できています。
viewDidLoadメソッドにて描画処理を行っています。イベントハンドリングなどもiOS開発に携わっている方なら違和感なく表現されているのではないでしょうか。
肝心のcommonの部分はAndroid、iOSどちらのプラットフォームでも利用されるロジックが入っています。
今回で言えばCalculatorアプリのコアである四則演算のロジックですね。
Androidで動かしてみる
とりあえず、Androidの実機を持っているので./gradlew android:installDebugします。
23:52:08: Executing external task 'installDebug'...
Configuration on demand is an incubating feature.
Incremental java compilation is an incubating feature.
:android:preBuild UP-TO-DATE
:android:preDebugBuild UP-TO-DATE
(中略)
:android:installDebug
Installing APK 'android-debug.apk' on 'SHV35 - 6.0.1' for android:debug
Installed on 1 device.
BUILD SUCCESSFUL
Total time: 41.502 secs
23:52:52: External task execution finished 'installDebug'.
無事アプリがインストールされました。
Calculatorという名前の通り、電卓ですね。
iOSでも動かしてみる
僕はiOSの実機は持っていませんが、MacBook ProなのでSimulatorで動かすこととします。
まず、Simulatorを起動しておきます。なんでも良いです。
./gradlew ios:moeLaunch -Pmoe.launcher.simulators=XXXXX(SimulatorのID)とやってやります。
しばらくすると起動します。Simulator遅いけど。
XXXXXの部分にはSimulator>Hardware>Manage Deviceで見ることの出来るSimulatorのidentifierです。
これにより、Simulatorと紐付けることができます。
はい、動きました!
ipaファイルを作りたいとかいう場合は開発チームとかprovisioning profileの設定とか色々ありますよね。
そういう場合はios/build.gradleに関連の設定を書いてやる必要があります。
moe {
signing {
// String, ID of the development team.
developmentTeam
// String, path to the provisioning profile or UUID.
provisioningProfile
// String, name of the provisioning profile (new in Xcode 8).
provisioningProfileSpecifier
// String, name of the signing identity
signingIdentity
}
}
詳しくはこちらに書いてますので、ご参照下さい。
https://github.com/multi-os-engine/moe-plugin-gradle/blob/master/README.md
Getting Started(Kotlin)
こちらもサンプルコードがGitHub上にアップロードされています。
大体すでに説明してしまったのでネタ切れ感がありますが、サンプルアプリがちょっと違います。
$ ls
KotlinCalculator KotlinRssReader README.md
KotlinMuseumMap NOTICE.txt
これも例のごとくREADME.mdに詳細が書いてあるのでご参照下さい。
KotlinCalculatorの中を見てみましたが、コードはjavaのサンプルと同じ内容でした。Gradleの構成も同じ。android、ios、commonとなっています。
ただ、Kotlinでガッとかかれています。おそらくIDEのコンバートを使ったんではないかと思われます(IntelliJ IDEAではJavaからKotlinにIDEが変換してくれます)。
コミュニティもちゃんとある
discussion出来る場もちゃんと用意されています。
Multi-OS Engine Forum
2017/2現在メジャーバージョーンがすでに出ており、RoboVMからの乗り換えも多い感じで、すでにユーザーが多いです。
議論も結構進んでいてハマりどころは調べればなんとかなりそう。
ドキュメントもきっちりしている印象です。
https://doc.multi-os-engine.org
まとめ
- Intel Multi-OS Engineは結構よく出来ている
- ARTベースなのでAndroidは普通に今まで通り
- iOSはJavaからnativeに変換してiOSランタイムで動くようにしている
- Android/iOSプラットフォームのアプリがJava or Kotlinのコードで作れる
- 現在メジャーバージョンでコミュニティも出来てきている
- ドキュメントも割りとある
- 各IDE(IntelliJ IDEA、Eclipse、Android Studio)のサポートもある
- ビルドツールのプラグインもある(Gradle、Maven)
結構良い感じなんじゃないかなあと思います。
参考URL
- http://nosix.hatenablog.com/entry/2016/11/01/233212
- https://www.infoq.com/jp/news/2015/08/multi-os-engine-ios-android
- http://www.isus.jp/smartphones/working-with-persistent-storage-part-1/
- https://doc.multi-os-engine.org/multi-os-engine/2_Introduction/Introduction.html
- https://www.xda-developers.com/intels-multi-os-engine-lets-you-make-android-or-ios-apps-using-java/
- https://multi-os-engine.org/start/
- https://github.com/multi-os-engine/moe-plugin-gradle/blob/master/README.md
追記
MOEは2017/02現在、バージョンは1.xですが、
バージョン2.xではLLVMのビットコードサポートが入るらしいです。
@snakemanさん情報ありがとうございます!
その関連で調べていると
フォーラムでDoes multi-os-engine have a roadmap?というやりとりを見つけました。
Does multi-os-engine have a roadmap?
ここから分かることとして
- RoboVMとパフォーマンス的な違いは無い(Intelのチームのbenchmarkによると)
- MOE 2.xではLLVMベースのバックエンドがMOEのARTに搭載されbitcodeをサポートする予定
- MOE 1.xのランタイムライブラリはApache Harmony(Android M)
- MOE 2.xのランタイムライブラリはAndroid N
- Androidのライブラリを使っているのはiOSとAndroidのプラットフォームでMOEのコードを少なくするため
ということです。Roadmapもありました。2.xは今年にはリリースされるようなのでこちらも楽しみですね。