SmartNews, IncでAndroidアプリを書いている森と申します。 好きな魔法使いは心先輩とアダラパタです。

ところで、僕が普段づかいしている携帯電話はIS03といいます。 理由はレディ・ガガが宣伝していてかっこよかったのと、5年弱使っていてまだ壊れないからです。 ですが搭載されているAndroid OSのアップデートは2.2.1(Froyo)で打ち止めとなり、使えるアプリも最近ずいぶん少なくなってしまいました。 しばらく前にもさるアプリが、起動直後Playストアに強制遷移させて端末が対応していない旨を表示する機能専用になってしまいましたが、おもしろいのでそのまま放置してあります。

このように世の中にはいろいろな人がいますが、すべからく「多様性は善」であります。 「世界中の良質な情報を必要な人に送り届ける」というミッションのもとできるだけ多くのユーザーをサポートするのが私たちの責務であると考えており、SmartNewsのAndroidアプリは未だAndroid OS 2.2から動作するよう開発が続けられています。 あと、僕の携帯で動かなくなると開発がめんどうという理由もあります。

010

こちらが最近のアクティビティから抽出したSmartNewsユーザーのAndroidバージョン比率です。 2.2系(合わせて0.1%程度)はともかく、無視できない数の2.3系ユーザーが使ってくださっていることがわかりますね。

なお、リリース当初はAndroid OS 2.1にも対応していた記憶がありますが、確かGCMのpush通知を動かせないためサポート外とさせていただきました。 その節については大変申し訳なく……

ともあれ、この記事ではわれわれが実践しているサポートのための工夫のいくつかを紹介できればと思います。

端末に合わせたUI

Googleによる公式Design Support Libraryの提供のおかげで、古い端末(2.1から!)でもMaterial DesignでUIを統一することが簡単にできるようになりました。 ですがSmartNewsアプリではいまのところ導入はせず、それぞれの端末固有の見た目を生かしています。 別にMaterial Designの理念(紙の質感と奥行きを生かした階層構造、なめらかな画面遷移、etc……)に真っ向反対するつもりはなく、ユーザーがふだん目にしているホーム画面やメーラーアプリなどと馴染むUIであったほうが不要な驚きを減らせるだろうという判断によるものです。

たとえばSmartNewsの設定画面はPreferenceActivity やPreferenceFragment を使わず独自に実装していますが、なるべくこれら標準のコンポーネントを用いたものと同じ見た目になるようにしています。 ソースを見れば実装がだいたい全部わかる点がAndroid最大のいいところですね。

IS03 (2.2.1) SO-04E (4.2.2) Nexus 6 (5.1)
ただし最新の端末で最新のUIを動作させるためにはAndroidManifest.xml におけるtargetSdkVersion の値には気をつける必要があります。 ここに指定されたバージョンが古いと、それ以降の端末でも古い動作をエミュレートするよう動作してしまいます。 従ってそれぞれの端末に見合った振る舞いをさせるためには、できるだけtargetSdkVersion は高く、minSdkVersion は低くという目標になります。

導入ライブラリに注意

Androidは裁判所お墨付きのとおりめでたくJavaで動いていますが、標準のJavaクラスであっても使えるものは限られており、
  • Android 2.2 (API level 8) まではだいたい Java SE 5 のAPIと互換
  • 2.3 (API level 9) から Java SE 6
  • 4.4 (API level 19) から Java SE 7
となっています。 無いからといってそれほど困ることはないかと思いますし、自分で書いているぶんには警告も出るので間違えることもないでしょう。 ですが導入する依存ライブラリで使われた場合には、エラーも警告もなくコンパイルできてしまうので注意する必要があります。

ちゃんとしたライブラリなら対応しているJDKバージョンは明記されていると思いますが、実行時にNoClassDefFoundError やNoSuchMethodError を吐くまで気づきにくいのがなかなか辛いところです(機械的なチェック方法も探せばありそうですが……)。 逆に言えばたとえコードが未対応のクラスやメソッドを参照していても、Javaの言語仕様上実際に使用するまではクラッシュしませんので、Build.VERSION.SDK_INT で分岐を入れれば使って問題ありません。

なおもともとAndroid用のライブラリであればそれ自体にminSdkVersion が指定されているので間違えて導入してしまう心配は無いでしょう。 逆に対応していないバージョンに無理やり入れることも、AndroidManifest.xml に次のような記述を加えれば可能になります。

<uses-sdk tools:overrideLibrary=“com.facebook.android”/>
SmartNewsアプリではFacebook SDKのライブラリを単にFacebook広告経由のインストール計測にしか使っていないため、対応バージョン以下では計測を諦めることで問題なく使用できています。

低スペック端末のケア

SmartNewsの個性ともいえる記事表示時のキューブアニメーションですが、実はAndroid 2.xの端末ではシンプルな平行移動のトランジションになります。
IS03 (2.2.1) SC-04E (4.3)
この部分のコードは3D変換行列を手書きしているだけなので別に2.xでも動かせるのですが、実際にやってみると一世代前の古い端末では描写のカクつきなどパフォーマンスに悪影響がありました。 このような基本的動作の部分でユーザーにストレスを感じさせては元も子もないため、必要最低限の挙動に切り替えてあります。 他にもたとえば特定の機種で日本語描画が異常に遅い、動画の再生がおかしいなど様々な事象があり、汎用的に対応できないものについてはその都度対処を行っています。

クラッシュ情報を活用

SmartNewsアプリにはTwitter社のCrashlyticsが組み込んであり、アプリで発生するクラッシュの統計情報を収集・解析しています。 これのおかげで万が一バグを仕込んでしまっても即座に調査して修正することが可能になりました。 ですがそこで気づきました、よく見ると自分で入れたバグよりAndroid OS自体のバグのほうが多い…… 例を挙げると とくに最初のやつ、非公式の謎野良リポジトリにしか該当コードが見当たらないし、なんなんだ、なんなんだおまえ。 AndroidのWebViewはあからさまに3のバージョンでアホになっており、悲しきかな中身がChromeに総入れ替えになった4.4まで完治しなかったようです。 正直2.2~2.3のサポートより3.0~4.3のサポートのほうが厳しい……

ともかく、こうして見つけたバグの一部はソースを漁ってリフレクションでprivateフィールドを無理矢理書き換えるなどの黒魔術で潰すことができました。 その甲斐もあり一日あたりクラッシュに見舞われないユーザーの割合は99.8%(最新版では99.9%)を維持できています。

07

この数字がどれだけ当てになるかは正直よくわかりませんが、そこそこ自慢できる水準のハズ。

セキュリティどうなの

あまり直視したくない話題ではありますが、古い端末についてまわるのがセキュリティ上のリスクです。 基本的にはOSが責任をもつべき部分だと考えていますが、一応「AndroidのWebViewの脆弱性についての私的なまとめ」に記載されているものなど気づいたところはチェックを行っています。 結論としては、この脆弱性に関しては各ベンダーが対処を行ってくださっているようでした。 ですがいつまでも信頼できるものでもないので、そろそろあまり意地を張らないほうがいいのかもしれない……

まとめ

思いつくさま書き出してみましたがそんなに大したこと書いていない、つまり裏を返せばそんなに大したことしなくても古い端末のサポートくらいできるということですので、ほどほどにがんばりましょう。

なお、弊社ではエンジニアを随時募集しているそうですよ。 このアプリにも改善したいところがまだまだ多々ありますので、興味のある方は是非お声がけください。