Crosswalk + Cordova で Android アプリを作成する

**この記事の内容は古いバージョンのCordovaについて書かれています.
最新版のCordovaではCrosswalkをプラグインとして扱えるようになっているので、より簡単にプロジェクトをセットアップできます.**
参考: [Crosswalk - Crosswalk with Cordova 4.0] (https://crosswalk-project.org/documentation/cordova/cordova_4.html)

## 動機

Cordova アプリケーションの UI を Polymer を使って書いたが, 手元の端末 (Android 4.2.2) では動かなかった.
この構成でアプリを正しく動かすためには Android 4.4 以上が必要らしい.

そこで Crosswalk を使うと良い, ということを書いてあるページを見つけたので実際に試してみた.

[Using Polymer With Apache Cordova] (https://blog.nraboy.com/2014/07/use-polymer-apache-cordova/#comment-1836528047)

> "To make a native Android application using Polymer and Cordova, you must first be aware that **it will work best with Android 4.4 and higher**. For whatever reason, earlier versions of Android may produce questionable results when rendering the CSS that Polymer requires."

> You need a web runtime that supports what Polymer offers. **If you wish to support lower versions, you need to install Crosswalk.**

## Crosswalk のインストール

参考: [Crosswalk - Developing a Crosswalk Cordova application](https://crosswalk-project.org/documentation/cordova/develop_an_application.html)

ツールセットをダウンロードする.
ターゲットが ARM 用と x86 用のツールセットが別々に存在するので, エミュレーターやモバイル端末に合わせて選択する.

```bash
$ wget https://download.01.org/crosswalk/releases/crosswalk/android/stable/10.39.235.15/x86/crosswalk-cordova-10.39.235.15-x86.zip
$ unzip crosswalk-cordova-10.39.235.15-arm.zip
$ cd crosswalk-cordova-10.39.235.15-arm
```

ツールセットのディレクトリを環境変数 `$CROSSWALK` に設定して, 使用するときは `$CROSSWALK/bin/create` のようにする.
(create や update は PATH に通したくなかったため.)

```bash
$ export CROSSWALK=`pwd`
```

動作テスト

```bash
$ $CROSSWALK/bin/create --help
Usage: bin/create <path_to_new_project> <package_name> <project_name> [<template_path>] [--shared]
    <path_to_new_project>: Path to your new Cordova Android project
    <package_name>: Package name, following reverse-domain style convention
    <project_name>: Project name
    <template_path>: Path to a custom application template to use
    --shared will use the CordovaLib project directly instead of making a copy.
```

## Cordova プロジェクトの作成

`create` コマンドでプロジェクトを作成する.

```bash
$ $CROSSWALK/bin/create \
> CrosswalkCordova \  # プロジェクトのディレクトリ
> com.habribe.crosswalkcordova \  # アプリケーション ID
> CrosswalkCordova  # プロジェクト名
```

ディレクトリの中身は以下のとおり.

```bash
$ cd CrosswalkCordova
$ ls
AndroidManifest.xml  assets/              cordova/             project.properties   settings.gradle
CordovaLib/          build.gradle         libs/                res/                 src/
```

アプリをビルドして実行する. この時 Android 実機を PC に接続しておくか, エミュレーターを起動しておく.

```bash
$ ./cordova/run
```

**MEMO**:
`./cordova/run` コマンドにはビルドをスキップしてアプリの実行を行う `--nobuild` オプションがあるが, 今回使用したバージョン (crosswalk-cordova-10.39.235.15-arm) ではエラーが出て使えなかった. 

以下, エラーメッセージ

```bash
$ ./cordova/run --nobuild
Skipping build...
/Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:126
                    throw e;
                          ^
TypeError: Cannot read property 'length' of undefined
    at /Users/haburibe/works/cordova/CrosswalkCordova/cordova/lib/build.js:334:35
    at _fulfilled (/Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:798:54)
    at self.promiseDispatch.done (/Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:827:30)
    at Promise.promise.promiseDispatch (/Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:760:13)
    at /Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:526:49
    at flush (/Users/haburibe/works/cordova/CrosswalkCordova/cordova/node_modules/q/q.js:108:17)
    at process._tickCallback (node.js:355:11)
```

## Polymer でアプリケーションを作成する

参考: [Using Polymer With Apache Cordova](https://blog.nraboy.com/2014/07/use-polymer-apache-cordova/)

index.html や cordova.js があるディレクトリに移動する.

```bash
$ cd ./assets/www
```

プロジェクトに bower を導入する.

```bash
$ bower init
(プロジェクト名やバージョンが聞かれるが, 特に入力することはないので Enter 連打)
```

Polymer 関係のパッケージをインストールする. `--save` オプションで依存関係を bower.json に追加する.

```bash
$ bower install --save Polymer/polymer
$ bower install --save Polymer/webcomponentsjs
$ bower install --save Polymer/core-elements
$ bower install --save Polymer/paper-elements
```

index.html を以下の内容に置き換える.

```html5
<!doctype html>
<html>
    <head>
        <title>Test Project</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
        <meta name="mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
        <link rel="import" href="bower_components/core-scaffold/core-scaffold.html">
        <link rel="import" href="bower_components/core-header-panel/core-header-panel.html">
        <link rel="import" href="bower_components/core-menu/core-menu.html">
        <link rel="import" href="bower_components/core-item/core-item.html">
        <link rel="import" href="bower_components/paper-toast/paper-toast.html">
        <link rel="import" href="bower_components/paper-fab/paper-fab.html">
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript">
            app.initialize();
        </script>
        <style>
            html, body {
                height: 100%;
                margin: 0;
            }
            body {
                font-family: sans-serif;
            }
            core-scaffold {
                position: absolute;
                top: 0;
                right: 0;
                bottom: 0;
                left: 0;
            }
            #core_toolbar {
                color: rgb(255, 255, 255);
                background-color: rgb(79, 125, 201);
            }
            #core_card {
                width: 96%;
                height: 300px;
                border-top-left-radius: 2px;
                border-top-right-radius: 2px;
                border-bottom-right-radius: 2px;
                border-bottom-left-radius: 2px;
                box-shadow: rgba(0, 0, 0, 0.0980392) 0px 2px 4px, rgba(0, 0, 0, 0.0980392) 0px 0px 3px;
                margin: 2%;
                background-color: rgb(255, 255, 255);
                text-align: left;
            }
            paper-fab {
                position: absolute;
                right: 20px; 
                bottom: 20px;
            }
        </style>
    </head>
    <body unresolved>
        <core-scaffold>
            <core-header-panel navigation flex mode="seamed">
                <core-toolbar id="core_toolbar">Navigation</core-toolbar>
                <core-menu theme="core-light-theme">
                    <core-item icon="settings" label="item1"></core-item>
                    <core-item icon="settings" label="item2"></core-item>
                </core-menu>
            </core-header-panel>
            <div tool>Test Project</div>
            <core-card id="core_card" vertical layout start>
                <div style="padding: 20px;">This is a sample project.  Please share my blog if you've found this useful</div>
            </core-card>
            <paper-toast id="toast1" text="Created by Nic Raboy"></paper-toast>
        </core-scaffold>
        <paper-fab icon="add" onclick="document.querySelector('#toast1').show()"></paper-fab>
    </body>
</html>
```

再度アプリをビルドして実行する.

```bash
$ cd ../../
$ ./cordova/run
```

実行結果 (本文では ARM 用のツールセットを使ったが, genymotion で実行するために x86 用のものを使用した.)

![スクリーンショット 2015-03-02 23.21.27.png](https://qiita-image-store.s3.amazonaws.com/0/2688/e140c495-f9cb-d732-2251-d4276097e981.png "スクリーンショット 2015-03-02 23.21.27.png") ![スクリーンショット 2015-03-02 23.21.41.png](https://qiita-image-store.s3.amazonaws.com/0/2688/d8d60c00-fa1e-a877-930d-8bd25e7c3197.png "スクリーンショット 2015-03-02 23.21.41.png")