Genymotion (旧 AndroVM) を Titanium Mobile で使ってみる

More than 5 years have passed since last update.


Genymotion (旧 AndroVM) を Titanium Mobile で使ってみる

Androidエミュレータが爆速で動くと話題の Genymotion (旧 AndroVM )。せっかくそんなに速いなら、Titanium Mobile から使えるようにしたい!と思いたち、試行錯誤をした結果なんとか使えるようになったのでメモ。


Genymotionって?

とっても動作が遅いと評判の Android Emulator を代替するプロダクト Genymotion

x86アーキテクチャのVM上で、Android Emulator を動かそう!ということ らしい。 細かいことは実はよく知らない。ちょっと前まで AndroidVM という名前だったことは知っている。商用プロダクトになったように読めるんだけど、今のところFreeで使えている。今後はどうなるか不明。

詳しくはこちらを。


この記事の前提

自分の使い方は少し特殊かもしれないけど、用途は満たしている。Genymotion を知ってしまったいま、今までの開発にはもう戻れないよ。すごい快適だよ。


  • Mac OS 10.8.4

  • Titanium Mobile SDK (3.1.1) と Andorid SDK は正しくインストールされ使えている

  • Android は 4.1 以降のみをターゲットにして開発

  • Titanium Alloy のみ利用

  • Titanium Stuido は使っていない。テキストエディタ + コマンドライン

  • Studioを使ってないのでブレークポイントなどを使った今どきのデバッグはしない


  • Vagrantを使っているので、すでに Host Only Network のアダプタが一つ登録されている


VirtualBoxのインストール

Macの場合は必要なのでインストールする。手順は割愛


Genymotionのインストール



  1. Genymotion にアクセスして、まずはユーザー登録を行う

  2. Mac OS X 64 bits用のインストーラー(dmgファイル)をダウンロード&実行して、Genymotion.appGenymotion Shell.appをインストールする


  3. Genymotion.appを実行

  4. 「なにもイメージがないけど登録するかい?」っぽいメッセージが表示される。迷わず「YES!!!」

  5. 登録したユーザーIDとパスワードでログイン

  6. 使いたい Virtual Device を選択して、ダウンロードとインストールと登録を行う。今回試したのは、「Galaxy Nexus - 4.1.1 - with Google Apps - API 16 - 720 * 1280」

  7. Genymotion 上に登録された仮想デバイスを Play する。初回は Android SDK のパスを聞かれるので設定する


VirtualBoxの設定

自分の環境では、すでに VirtualBox 上の仮想マシンが存在したからかもしれないけど、上記手順までやって Play しても、IPアドレスがほげほげと言われて動かなかった(´・ω・`)。きっと VirtualBox Host-Only Ethernet Adapter の vboxnet0 が使用済みだったからだと思う。


  1. VirtualBox (Oracle VM Virtual Box Manager)を起動して、VirtualBox自身の設定(各VMの設定では ない)を表示する

  2. [Network]を表示して[Host-only Networks]を追加する。vboxnet1が追加された


  3. どうも Genymotion で動くVMは、 192.168.56.X/24 の Host-only Network を使うっぽい。vboxnet1に以下のように設定を行った

    Adapter

    IPv4 Address:192.168.56.1

    IPv4 Network Mask:255.255.255.0

    DHCP Server

    Enable Server:チェックを入れる

    Server Address:192.168.56.1

    Lower Address Bound:192.168.56.100

    Upper Address Bound:192.168.56.119



  4. Genymotion によって VirtualBox 上に登録された、Android VM の [Settings]を開き、[Network]の[Adapter1]に、先に追加したvboxnet1を指定する。[Attached to]は、[Host-only Adapter]を指定



  5. [Adapter2]には、[NAT]を指定した




  6. Genymotion に戻り、[Play] で実行できるはず




いまはどんな状態?

無事に Mac 上で動いた Genymotion。確かにサクサク動作する。それで今はどんな状態なんだろう。

adb devicesを実行すると、Genymotion の VM は device と表示される。ただし adb -d shellはエラーになり、adb -e shellにしないと入れない。つまり Genymotion はエミュレータ扱い。

$ adb devices

List of devices attached
192.168.56.100:5555 device

$ adb -d shell
error: device not found
$ adb -e shell
shell@android:/ $


コマンドラインから Titanium アプリをインストール

Titanium コマンドラインからAndroid 向けビルドを行なえば、adb コマンドでインストールできるはず。ということでやってみる。この辺りは、Titanium なみなさんに色々と教えてもらった。ありがとうございます。


  1. Genymotion で Android の VM が動いていることを確認



  2. Titanium プロジェクトのディレクトリへ移動する

    $ cd Project-Directory
    



  3. Titanium で Android 向けにビルド。エミュレータへのインストールや実行などは行わないフラグをつける

    $ titanium build --platform=android --build-only
    



  4. build/android/bin/app.apk にアプリがビルドされている。-sでデバイスを指定してインストール

    $ adb -s 192.168.56.100:5555 install -r build/android/bin/app.apk
    


  5. Genymotion にアプリがインストールされている。実行。サクサク。感激!



  6. もちろん、こうやってコマンドをつなげてもOK

    $ titanium build --platform=android --build-only && adb -s 192.168.56.100:5555 install -r build/android/bin/app.apk
    



  7. Cleanをしたほうがいいとの情報も有り。僕は不要なんだけど、ちょっと分からない。

    $ titanium clean && titanium build --platform=android --build-only && adb -s 192.168.56.100:5555 install -r build/android/bin/app.apk
    


  8. これで思う存分 Android の開発ができるね!



もう一歩前へ

!!!!ここから先は、Titanium に慣れてない人、オススメできないです!!!!

ここまでで Titanium 製のアプリを Genymotion へインストールするところまで出来た。ただ自動でアプリを起動しないところが気に入らない。Titanium Mobile SDK を改造して、通常のエミュレータと同じように動くようにしてみる。


Titanium Mobile SDK の編集

この手順は自分で試行錯誤したというより、ほとんど「開発系もろもろ」さんを参考にさせて頂いた。ありがとうございます。

Titanium コマンドが、「オマエはエミュレータだな?」と判断する基準は、adb devicesコマンドで表示されるデバイスの名前が、「emulator-」ではじまっていること。

Genymotionは「192.168.56.100:5555」みたいな名前になるので、Titanium コマンドからはエミュレータ扱いされない。

そのため、Titanium Mobile SDK 内部の Python と Node.js スクリプトをイジって、強制的にエミュレータとして認識されるようにした。正直IPベタ書きで気に入らないけど、とりあえず動くからOKにしてる。いい方法があったら是非教えて下さい...。


Titanium/mobilesdk/osx/3.1.1.GA/android/androidsdk.py

        # 300行目付近

for line in out.splitlines():
line = line.strip()
if line.startswith("List of devices"): continue
elif line.startswith("emulator-"):
(name, status) = line.split()
port = int(name[name.index("-")+1:])
offline = False
if status == "offline":
offline = True
devices.append(Device(name, port, True, offline))
# ↓↓↓↓ 追加 ここから ↓↓↓↓
elif line.startswith("192.168.56."):
(name, status) = line.split()
port = int(name[name.index(":")+1:])
offline = False
if status == "offline":
offline = True
devices.append(Device(name, port, True, offline))
# ↑↑↑↑ 追加 ここまで ↑↑↑↑
elif "device" in line:
name = line.split()[0]
devices.append(Device(name))


Titanium/mobilesdk/osx/3.1.1.GA/android/_build.js

// 465行目付近

devicesProcess.on('exit', function (code, status) {
if (results.indexOf('emulator') != -1) {
logger.info(__('Emulator is running') + '\n');
// ↓↓↓↓ 追加 ここから ↓↓↓↓
} else if (results.indexOf('192.168.56.') != -1) {
logger.info(__('AndroVM Emulator is running') + '\n');
// ↑↑↑↑ 追加 ここまで ↑↑↑↑
} else {
emulatorRunning = false;
logger.info(__('Emulator process exited successfully') + '\n');
logcatProcess && logcatProcess.kill('SIGKILL');
adbProcess && adbProcess.kill('SIGKILL');
buildProcess && buildProcess.kill('SIGKILL');
emulatorProcess = buildProcess = logcatProcess = adbProcess = null;
}
});


実行


  1. Genymotion で Android の VM が動いていることを確認



  2. 以下のコマンドを発行

    $ cd Project-Directory
    
    $ titanium build -p android


  3. Androidエミュレータが起動してしまうので 素早く終了する 。終了しないと「エミュレータが2つ以上います」って感じのエラーになる


  4. Android の VM 上でアプリが実行される


起動してくる Androidエミュレータ を素早く終了するのは面倒なので、またまた Titanium Mobile SDK を編集する。

ただし以下の修正を行うと、(たぶん) Titanium Studio などから普通の Androidデバッグ をやろうとしても、エミュレータが起動しないと思うので注意。


Titanium/mobilesdk/osx/3.1.1.GA/android/_build.js

// 448行目付近

// これをコメントアウト
// emulatorProcess = spawn('python', emulatorCmd, { detached: true, stdio: 'ignore' });

// 動かしたくないからこうする
emulatorProcess = spawn('python', ['--version'], { detached: true, stdio: 'ignore' });


以上!!

Code Strong!!