minimoにInstantAppsを導入しようとした話

mixi Group Advent Calendar 5日目
[サロンスタッフ直接予約アプリ](https://minimodel.jp)というサービスのAndroidアプリを作っている@moroku0519といいます。

今年2017年新卒としてmixiグループに入社しました。

さて、みなさまはAndroid Instant Appsをご存知でしょうか？

# Android Instant Apps
実際の動作はこちらをご覧ください。
https://www.youtube.com/watch?v=cosqlfqrpFA
Instant Appsは2016年のGoogle I/Oにて発表されました。
Instant Appsは、アプリをインストールすることなく、そのアプリの機能の一部を使うことができます。
軽量であるので、ユーザがアプリの機能をすぐにダウンロードしてきて気軽に体験することができます。使い終われば自動的に端末から削除されます。
（容量がいっぱいでインストールできない...!!ということも少なくなる）

観光地などのガイドアプリ（その場でしか使わないアプリ）なんかも相性がいいのではないかと思います。

Instant Appsはデベロッパーが指定したURLをユーザが踏むことで起動し、ダウンロードしてきて使うことができます。
Webページにアクセスした感覚で、ネイティブアプリの機能が使えます。

# minimoとInstant Apps
Instant Appsを使うことで、手軽にサロン予約ができるのではないか？という話がチーム内で上がりました。
minimoをインストールしていないユーザが、minimoのWebページでサロンを見ていて「あ、ここいいじゃん!!」て思った時にInstant Appsで予約ができたら、アプリをインストールすることなく手軽に予約ができます。
そうしていいサロン体験ができたら、minimoをインストールしてもらえるのではないかと考えました。

# Instant Appsにおけるマルチモジュール化
既存のプロダクトからInstant Appsを作るのに、1から作る必要はありません。
Android Studio3.0とInstant Apps SDKを用意します。
そこから、プロジェクトをマルチモジュール化します。

Instant Apps対応するために、プロジェクトをマルチモジュール化します。(figure1)
Instant Appsと通常のアプリはそれぞれのfeature moduleから構成されます。

figure1
![20071104232905.jpg](https://developer.android.com/topic/instant-apps/getting-started/images/aia-features-multi.png?hl=ja)

## Base Feature
BaseFeature はInstant Appと通常のアプリの両方で使うコードで構成されています。
まさにアプリのbaseとなるmoduleです。

base moduleとなるmoduleにはcom.android.featureのプラグインと、base moduleとなることを宣言する必要があるため、
Base Featureのbuild.gradleには以下の記述をします。

```
 apply plugin: 'com.android.feature'
    android {
        ...
        baseFeature true
        ...
    }
```

## feature module

feature moduleはその名の通り、必要な機能群のコードが入っているmoduleです。
Instant Appsで提供したい機能をfeature1 moduleに入れ、feature2 moduleに残りの機能を入れる、といった構成が挙げられます。
しかし、注意しなければいけないのは、**feature moduleのapk サイズは 4MB 以下に抑える**ことをGoogleが推奨していることです。
対規模なアプリをInstant Apps対応する際、feature moduleの構成に注意しなければいけません。

## Instant Apps module

instant Apps moduleにはプロダクトコードを含みません。
ここでのbuild.gradleにはcom.android.instantappプラグインのapplyと、dependenciesにてこのmoduleにて実装するfeature moduleを書きます。

```
apply plugin: 'com.android.instantapp'
...
dependencies {
    implementation project(':base')
    // if there additional features, they go here
    implementation project(':feature1')
}
```

この記述によって、Instant AppsではBase Featureとfeature1をapkとしてビルドすることが定義されました。(figure2)

![instant app modules2.png](https://qiita-image-store.s3.amazonaws.com/0/28622/899d50cf-4bf2-bf48-3c38-d67aef1cf5a9.png)

## App Module
Instant Apps moduleと同様、コードは含みません。（ただし、Instant Appsと異なり、Manifestは含まれる）
build.gradleに、com.android.applicationプラグインのapplyと、必要なmoduleを記述します。

```
apply plugin: 'com.android.application'
...
dependencies {
    implementation project(':base')
    // if there additional features, they go here
    implementation project(':feature1')
    implementation project(':feature2')
}
```

figure3
![instant apps module3.png](https://qiita-image-store.s3.amazonaws.com/0/28622/0550b110-262d-5901-31f6-a6d1dc2800dc.png)

## minimoにおけるマルチモジュール化
minimoでは、マルチモジュール化するにあたって、以下の構成にしました。(figure4)

figure4
![minimoInstantApp.png](https://qiita-image-store.s3.amazonaws.com/0/28622/8a5c23ba-dc38-da76-4fa9-117f7ac07c0b.png)


InstantAppに必要なfeature moduleは主に予約機能群だったため、　minimoFeatureReservationとしてmodule化しました。

reservation系のクラスからの依存によってやむおえずminimoBaseに含まれているものもあります。

このマルチモジュール化に一番時間がかかり、1ヶ月ほど時間がかかったかとおもいます。

# ようやく運用...と思いきや

Android Studio3.0には**Base Feature以外でDatabindingが動かない**というバグがあり、Databindingをfeature moduleに含めた構成にしているとビルドできません。

https://issuetracker.google.com/issues/63814741

minimoでもDatabindingは使用しており、このバグによってInstant Appsをリリースできていません...orz

このバグがminimoチームで発見された時、（2017年9月上旬）issue TrackerにてGoogleの中の人が

> we are shooting for early 3.1 (one of the alpha releases).

と言っていたので、3.1まで直りそうもねえええええええとチームのAndroidエンジニア一同頭を抱えました。

Android Studio3.0のbeta, stableが出るたびにバグが修正されたか確認しましたが、相変わらずnon-baseなfeature moduleではDatabindingが使えない状態でした。
もはやGoogleがおおかみ少年に思え、
「新しい3.0が出たぞおおおお」とGoogleが言ってきても
「そうなんだふ〜ん」と興味をほとんど失っていました。

# それから時は流れ3.1 Canary release

ついに、中の人が公言していた3.1がCanaryという形ですがリリースされました。
別タスクなどに追われ、Instant Appsのことが後回しになり、試せていなかったのですが、
issueTrackerを見てみると...


>On that note, Android Studio Canary 3.1 is available. In this version, you will be able to add "android.enableExperimentalFeatureDatabinding=true" to your gradle.properties file to bypass the databinding disabling check. Doing so is not officially supported. For the most part, actual databinding will only work with resources in the base feature. Any attempt at using databinding with a resource not in the base feature will cause the app to crash at runtime. Note, we offer no guarantee that databinding will work correctly with resources in the base feature either until we have a proper resolution.

つまり、完全には直っていないと...

リリースできるのはまだまだ先みたいです。合掌。

# おわりに
minimoにInstant Appsを導入しようとした話を書かせていただきました。
まだまだInstant Apps対応しているアプリはそんなになく、実用段階には至っていないのかなという印象をうけます。
しかし、Instant Appsの構想自体はおもしろく、私たちのような予約サービスにとっても相性が良く、UXの向上が図れるのではないかなーと感じています。

まだまだInstant Appsとの戦いは続きそうです。

minimoでは、これからもサロンスタッフとお客さんとのマッチングをサポートできるよう、サービスの向上を図っていきます。
以上、mixi Advent Calendar 5日目

minimoにInstantAppsを導入しようとした話

でした！！

# おまけ

橋本環奈さんの出演するTVCM放送しています。
見ないともったいないない♪

https://www.youtube.com/watch?time_continue=3&v=dCR2zHRy8ug