「AndroidシステムのWebView」を更新しよう

AndroidシステムのWebViewとは

Android 5.0から最新のWebViewはGoogle Playで更新されるようになりました。これにより「AndroidシステムのWebView」というアプリを更新することで、Chrome(Chromium)をベースとした、バグが修正されたWebViewを利用することができます。バグが修正されるということは、更新しておくとセキュリティ面でも安心です。

WebViewを利用しているアプリは多いので、セキュリティ問題が含まれたままの古いWebViewを利用していると、なんらかの攻撃を受けるリスクはかなり高くなります。

また、そのようなマイナスを減らすというだけではなく、更新することで新しいWeb技術を利用できるというプラスもあります。

ということで、Android 5.0以上の端末において「AndroidシステムのWebView」は是非とも更新すべきアプリの一つです。

2016年2月9日版までのWebViewのクラッシュ問題

(いつからかまでは特定できていませんが)2016年2月9日のバージョン48.0.2564.106までの「AndroidシステムのWebView」にはかなり重大なバグが潜んでいました。

このリンク先のissueがそれを示したものなのですが、簡単にまとめると「WebViewを利用したアプリがランダムに落ちる」というものです。

OpenGL関連のネイティブライブラリ内でクラッシュするようで、アプリ側で例外をキャッチして回復処理を行うということもできません。またランダムというのもくせものでした。弊社での確認でもそうだったのですが、この問題はAndroid 6.0および6.0.1上でのみ発生しているようでした。

ただ、一応アプリ開発する上での回避方法はありまして、以下のようにすることで回避できていました。

WebView webView; // この変数にWebViewインスタンスをセット
....
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

これがどういうことをやっているかというと、「指定したWebViewの描画にハードウェア支援(GPUによる描画支援)を使用しない」という設定です。つまり回避のためにこの設定を行うと、WebViewの表示が遅くなりメモリ使用量も増えるというデメリットがあります。

Android 6.0以降が搭載された端末は非常に限られていたことや、パフォーマンス問題を引き起こすことを嫌うことなどから、回避策を入れていないアプリも多いと考えられます。

アップデートによる改善

Alex Mineer氏によると、49.0.2623.63がベータ版としてリリースされ、問題なければ正式にリリースされるとのことです。

issueのコメントによると、49.0.2623.55には問題のworkaround(回避策)が入っていますので、正式にリリース予定のバージョンでは問題は改善している見込みです。

弊社でWebViewのテスター登録を行ってベータ版をインストールしてみたところ、以前は落ちることがあったものが安定することを確認しました。

2016年春以降、Android 6.0端末急増の見込み

日本国内でも大手キャリアのAndroid端末に対するAndroid 6.0へのアップデートが始まります。たとえば、 NTTドコモによるAndoid 6.0へのアップデートのお知らせが出ています。

旧機種へのアップデートが行われるということは、今年の春夏モデル端末にはAndroid 6.0が搭載されてくるでしょう。

特にアップデートによってAndroid 6.0になるものについては、古いWebViewが搭載されたままとなっている可能性が高いでしょう。試験にかかる時間などを考えると、2月下旬に公開されたものを組み込んだ状態でアップデートがリリースされるとは考えにくいためです。

アプリ開発者はどうするべきか?

  • 6.0以降の端末である
  • 端末内の「AndroidシステムのWebView」のバージョンが古い
  • アプリ内でWebViewを利用している

上記の3つがAND条件で成立する場合、ユーザを「AndroidシステムのWebView」の更新に誘導してもよいかもしれません。

ユーザはどうするべきか?

AndroidシステムのWebView」を更新しましょう。アプリがクラッシュするのを少しでも減らせるのはよいことです。

DroidKaigi 2016:「 Andoridの省電力について考える」に対する補足

弊社代表の中西がDroidKaigi 2016にて「Androidの省電力について考える」というタイトルでセッションを担当いたしました。

以下にその際に用いた資料を示します。

また、上記の資料では説明しきれなかったDozeの細かい話について少しだけ補足をします。

Android 6.0 Dozeの状態遷移

Dozeに入るまでの状態の変化については、同イベントでのSmartium株式会社の江川さんによるセッション資料の以下のページが参考になります。

あくまでも簡略的な図であり、正確な状態遷移について知りたい方はコードを追いかけてみてください。

資料には状態を遷移する時間が記されていますが、その情報はDeviceIdleControllerクラスのupdateConstants()メソッドの定義を見るとよいでしょう。状態遷移についてはstepIdleStateLocked()を確認するとわかります。

stepIdleStateLocked()を見ると、状態はACTIVE -> INACTIVE -> IDLE_PENDING -> SENSING -> LOCATINGというように段階を追って遷移していくことが示されています。
LOCATING後すぐにIDLE_MAINTENANCEに遷移し、一定時間後にIDLEへと遷移し、IDLEからもまた時間が経つとIDLE_MAINTENANCEへと遷移するというようなコードとなっています。

Doze突入の判定と継続の条件

DozeServiceクラスを読むことで、どういう条件でDozeに入るのか、またDozeが継続されるのかがわかります。

資料に簡単に記載しましたが、DozeServiceはAPI Level 17で導入されたDaydreamという機能をベースに実現されています。言いかえると「DozeServiceはDreamServceを継承したサービス」です。

Daydreamはスクリーンセーバーを実現する機能であり、画面がOFFになるタイミングで働き始めます。そのタイミングから各種の条件が成立するかの監視を開始し、成立すると先に挙げた状態遷移が行われるというわけです。

資料にも簡単に記載しましたが、面白いところとしてはコードの中でpulseと表現されている事象(たとえば端末が動かされる)が発生することがIDLE状態から抜けるトリガとなるのですが、近接センサ(proximity sensor)で端末が何かの物体と近接している場合には抜け出すトリガは捨てるという処理があります。コードを細かく見ていきコメントなども確認するとわかるのですが、これは端末がポケットやかばんに入っている場合にはDozeで省電力モードのままとするための処理です。

Dozeはディープスリープか?

ディープスリープは端末として最低限の電力消費まで機能を落としている状態であるとするなら、弊社で調べた限りではDoze自体がディープスリープとは言えないのではないかと考えております。

いわゆるACPU(アプリが動作するプロセッサ)は動作しシステムとしてはネットワーク通信もしている状態です。除外設定されたアプリは普通に動いています。そうでなければ高優先度のGCMを受け取って即時に対象のアプリに渡すということもできません。

Dozeによる省電力に対して非協力的なアプリが多いと、省電力効果は限定的になるだろうと考えられます。

そのため、Androidの将来バージョンにおいて更なる強制的な制限が行われることを避けるためにも、アプリ開発者ができるだけ省電力に対して協力的になることは非常に大事なことだと考えております。