2013年8月6日火曜日

世界平和とAndroid

このエントリーをはてなブックマークに追加
エンジニアの草苅です。
スマートフォンを扱うエンジニアの皆さんは、日々Android のバグに悩まされているのではないかと思います。弊社も類に漏れず様々な Android のバグと戦っています。

特にあんさんぶるガールズ!ではアニメーションはすべて Canvas を利用していることもあり、Android の Canvas 絡みのバグに、頭を痛めています。

Android のバッドノウハウは悩んでいる人みんなで共有した方が、世のため人のためになるのではと思い立ったので、世界平和を願っていくつかまとめてみたいと思います。

1. GPUレンダリングの設定によって Canvas で不具合が発生する

Android は OS のバージョンや、WebView のレンダリングエンジンの違いによって、GPUレンダリングOFFの場合に、Canvas が正常に表示できない端末、もしくはGPUレンダリングONの場合に、Canvas が正常に表示できない端末が存在します。

このような問題は、できれば Android OS のバージョンで統一しておいて欲しいのですが、どうも機種依存のようなので、弊社では機種に応じて GPUレンダリングONなのか、OFFなのかを個別で指定しています。

いくつか実例を挙げますと、現在のドコモのツートップ Xperia A と Galaxy S4は GPU レンダリングOFFでなければ WebView 上の Canvas は正常動作しません。それとは逆に、Nexus 7 や Arrows X は GPUレンダリングON でなければ WebView 上の Canvas は正しく表示されません。また、同じ OS のバージョンであっても Galaxy Nexus はGPUレンダリングONだとクラッシュし、Nexus 7はGPUレンダリングONでなければ Canvas が正常に表示されないということが発生します。

そのため、あんさんぶるガールズ!では、ONまたはOFFでしか動作しない端末については、次のようなメソッドを使って、アプリ側で強制的にGPUレンダリング設定を変更しています。


protected void setHardwareAccelerationEnabled(boolean enable) {
  if (enable) {
    getWindow().setFlags(
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
  } else {
    // 下位互換性を保つため、以下のコードをリフレクションで実行
    // webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    try {
      Method setLayerTypeMethod = webView.getClass().getMethod("setLayerType", new Class[] {int.class, Paint.class});
      setLayerTypeMethod.invoke(webView, new Object[] {View.LAYER_TYPE_SOFTWARE, null});
    } catch (NoSuchMethodException e) {
      // Older OS, no HW acceleration anyway
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
  }
}


2. GPUレンダリング設定以外に Canvas 周りのバグがある

Android 4.0.4 には Canvas がブラウザを巻き込んでクラッシュするというバグがあります。このバグは上記のバグと違い、WebView では再現しにくいのですが、ブラウザではかなりの頻度で発生します。

例えば Galaxy S3、Xperia SX、Xperia GX などの端末が Android 4.0.4 を搭載しています。CreateJS のコミュニティにもこの問題は上がっており、かなりの期間対処法がなかったのですが、その後、Canvas を clearRect する際、縦横に 1px だけ加えたサイズをクリアするようにすることでクラッシュしなくなるという、華麗なテクニックが編み出され、この方法が EaselJS 0.6 系に取り込まれました。

CreateJS のコミュニティの該当エントリー
http://community.createjs.com/discussions/easeljs/220-samsung-galaxy-s3-stock-android-404-browser-freezescrashes-on-stageupdate

修正のコミットログ
https://github.com/CreateJS/EaselJS/commit/7c02f0d4a7e50908b284623d23e6897f15e3bff4


また、Galaxy S4(Android 4.2.2)に関しては WebView 上で表示させたときだけ、Canvas が正しく表示されない不具合があります。
GPUレンダリングONの場合は、Canvas 全体が常に水色表示で何も出ず、OFFの場合はアニメーションが表示されたり、されなかったりがかなり不安定になってしまいます。もろもろ調べていると、日本語で次のようなブログ記事を見つけました。

Galaxy S4のWebviewで、非同期処理の中でのCanvasの描画がバグってる - 車輪を再発明 / koba04の日記
http://d.hatena.ne.jp/koba04/20130629/1372437341

この記事を見ながら「最新端末で動作しないアプリって…」と絶望していたのですが、諦めず調べていると安定してアニメーションを表示できるスピリチュアルな方法を、編み出すことができました。それはアニメーション表示直前に Canvas をクリアすることです。CreateJS であれば、Stage を作って、まずクリアしてからアニメーションを実行すると WebView 上の Canvas でも安定してアニメーションを表示することができました。

var canvas = document.getElementById('canvas');
var stage = new createjs.Stage(canvas);
stage.clear();
// clear した後アニメーションのコードを実行

3. GPUレンダリングOFFで特定のCSSが激重

さて、Canvas を正常に表示するためにGPUレンダリングを強制OFFにしたまでは良かったのですが、それに伴いスクロールが激重になってしまった端末があります。

例えば、今年の初めに発売されてツートップの発売前までドコモが推していた Xperia Z という端末は、WebView 上の Canvas を正常に表示するために GPUレンダリングを強制OFFにしたまでは良かったのですが、ほとんどのページでスクロールが激重になってしまいました。

いろいろ調べていると、shadow 系などアルファブレンディングを行うような css が GPUレンダリングOFF だと重くなってしまうようです。参考までに以下のような記事があります。

[CSS] border-radiusとbox-shadowを組み合わせると、それぞれ単体でのスタイルより5倍重たい!? - YoheiM .NET
http://yoheim.net/blog.php?q=20130713

単純に考えると、GPUレンダリングOFFの端末のみ、これらの css の重いプロパティを使用しない css で上書くというのが良さそうです。

Android には幸いなことに、Java Object を JavaScript Object として WebView に渡せるという、セキュリティ問題がとても発生しやすい、さわやかな機能があるので、これを利用します。そして、css を読み込む際、この WebView がGPUレンダリングOFFであれば、上書きする css を読み込むようにしました(以下は簡易的に書いたサンプルです)。

// this を droid という名前で JavaScript からアクセスできるようにします
webView.addJavascriptInterface(this, "droid");

// GPUレンダリングOFFのときのみ、上書き用のCSSを読み込みます。
if (!droid.webView.isHardwareAccelerated()) {
  var fileref = document.createElement("link");
  fileref.setAttribute("rel", "stylesheet");
  fileref.setAttribute("type", "text/css");
  fileref.setAttribute("href", '<%= path_to_stylesheet 'android_without_hardware_acceleration' %>');
  document.getElementsByTagName("head")[0].appendChild(fileref);
}


4. キーボード入力時に上下に揺れる端末

Android にはテキストボックスに文字を入力しようとすると、文字入力のたびになぜか画面がスクロールして、激しく上下に縦揺れするという恐ろしい端末があります。

例えばこちらに不具合が上がっています。
https://github.com/scottjehl/Device-Bugs/issues/32

あんさんぶるガールズ!では当初、コメントはすべてポップアップ画面でその場で入力できるようにしていましたが、この不具合に対応するため、Android はすべて画面遷移でテキストボックスが1つだけある画面に遷移した後、コメントを入力するように変更しました。さらに、テキスト入力中にスクロールが発生しないように、テキストボックスにフォーカスが当たった際、JavaScript でスクロールをなくす処理を入れています(以下はサンプルコードです)。

.stop-scroll {
  outline: none;
  overflow: hidden;
}

$('input[type=text]').on 'focus', (e)->
    $('body').addClass('stop-scroll')

$('input[type=text]').on 'blur', (e)->
    $('body').removeClass('stop-scroll')


おわりに

最後にうちのチームの優秀なアルバイトエンジニアの心の叫びを掲載して、世界平和を切に願いたいと思います。



Happy Elements 株式会社では世界平和を目指すエンジニア社員、およびアルバイトを募集しています。

Find Job!

Wantedly

Happy Elements株式会社 JOBS

9 件のコメント:

  1. Thanks for sharing, nice post!

    ATS - địa chỉ bán vong em be tu dong tại TP.HCM. Máy đưa võng hay gia may dua vong tu dong là sản phẩm tinh túy. Với sp may dua vong ts trở thành 1 phần của các gia đình với may dua vong nhưng bạn hãy cẩn thận với hàng giả với dung cu dua vong tu dong hoặc siêu mắc. Bạn cần tham khảo máy đưa võng giá rẻ trước khi mua hay những meo giup be ngu ngon hq hay thực phẩm giúp bé ngủ ngon các mẹ cần biết, hay sản phẩm nôi võng giúp bé ngủ ngon!

    Đến với bruno - shop thời trang UNIQLO chính hãng uy tín cho bạn, tại đây bạn có thể chọn thoi trang nam hang hieu sành điệu hay áo nam hàng hiệu cực cá tính, với các loại áo khoác nam hàng hiệu với nhiều mẫu hay áo sơ mi nam hàng hiệu thời trang cho bạn, với kiểu áo sơ mi nam tay ngắn cá tính hay tay dài áo sơ mi nam tay dài tha hồ lựa chọn. Tại Bruno, bạn có thể chọn áo sơ mi nam công sở hàng hiệu cực đẹp hay loại áo sơ mi trắng với áo sơ mi trắng nam hàng hiệu nhìn là thích hay, hay áo caro với áo sơ mi caro nam cực sành điệu với hàng hiệu chính hãng uy tín tại TP.HCM.

    Những thực phẩm giúp đẹp da tại http://nhungthucphamgiupda.blogspot.com/
    Thực phẩm giúp bạn trẻ đẹp tại http://thucphamgiuptre.blogspot.com/
    Thực phẩm làm tăng tại http://thucphamlamtang.blogspot.com/
    Những thực phẩm giúp làm giảm tại http://thucphamlamgiam.blogspot.com/
    Những thực phẩm tốt cho tại http://thucphamtotcho.blogspot.com/
    Những thực phẩm tốt cho da tại http://thucphamtotchoda.blogspot.com/
    Chăm sóc da mặt ở http://chamsocdamato.blogspot.com/
    Cách chăm sóc da mặt bằng http://cachchamsocdamatbang.blogspot.com/
    Dạy trẻ sơ sinh tại http://daytresosinh.blogspot.com/
    Bí quyết giảm cân hay tại http://biquyetgiamcanhay.blogspot.com/

    返信削除
  2. fado mua sắm khắp nơi trên thế giới. Chỉ cần vài thao tác trên internet bạn có thể dễ dàng mua được những món hàng trên Amazon của Mỹ hoặc Nhật bản và tất cả các nước khác trên thế giới.
    Phương thức thanh toán uy tín, tin cậy, nhanh chóng, báo giá cho khách hàng chỉ sau vài phút khi khách hàng lựa chọn sản phẩm.

    返信削除
  3. Bạn nên biết về cach lam thach rau cau 3d
    Thạch rau cau nâng cao sẽ có tại cach lam thach rau cau nhieu tang
    Bạn sẽ vô cùng ngạc nhiên với cach lam thach rau cau tai nha
    Hãy làm điều gì đó ý nghĩa khi chọn qua tang valentine y nghia cho nguoi yeu
    Đừng bao giờ bỏ qua qua tang valentine y nghia cho ban gai
    Bạn sẽ thích những món qua tang valentine y nghia nhat
    Cùng tìm hiểu stt tam trang ve tinh yeu cuoc song
    Giúp tình yêu thêm nồng nàng với nhung stt tinh yeu hay nhat
    Đôi khi bạn buồn thì hãy đến với stt tam trang buon co don

    返信削除
  4. Rối loạn cương dương là gì?Mặc dù là vấn đề nhạy cảm, nhưng vài năm gần đây, rối loạn chức năng cương dương đã trở thành đề tài nóng hổi ở các cuộc trà dư tửu hậu của cánh mày râu
    Dấu hiệu và cách khắc phục bệnh rối loạn cương dươngTuy nhiên, có nhiều nam giới do một số lý do nào đó mà chức năng sinh dục không thể duy trì được như mong muốn khiến họ vô cùng lo lắng và tự ti.
    Hướng dẩn cách làm tỏi đen tại nhàVậy bạn đã biết cách làm tỏi đen tại nhà chưa? Đừng lo, sau đây mình xin Hướng dẩn cách làm tỏi đen tại nhà vô cùng đơn giản, hãy cùng tham khảo nhé!
    Nhân sâm tươi Hàn Quốc có tác dụng gì?Dường như đã không còn xa lạ với con người, nhân sâm Hàn Quốc là một loại thảo dược thiên nhiên quý giá chứa nhiều thành phần dưỡng chất quan trọng có tác dụng tốt đối với sức khỏe.
    Trẻ sơ sinh ho có đờm phải làm sao?Củ cải rửa sạch, thái thành miếng nhỏ, sắc cùng với hai thứ kia để uống. Bài thuốc này dùng để chữa ho do lạnh, chảy dãi.
    Ho có đờm đặc kéo dài lâu ngày uống thuốc gì?Hấp cách thủy mật ong, gừng thái lát và quất tắc. Mỗi lần hâm nóng lại 1 – 2 thìa canh cho người bệnh uống vào sáng và tối
    Cách chữa ho có đờm cho trẻ emNướng trực tiếp trên lửa nhỏ và liên tục lật quả cam để vỏ không bị cháy. Nướng chừng 10 phút là được
    Cây huyền sâm là gì có tác dụng thế nào?Cây hắc sâm chữa bệnh rất tốt, cây hắc sâm có tác dụng thanh nhiệt giáng hỏa, sinh tân, dưỡng huyết, có tác dụng giải độc, tiêu viêm, nhuyễn kiên tán kết
    Cam thảo đất có tác dụng gì?Trong y học cổ truyền và y học hiện đại, cây cam thảo đất được nghiên cứu có tác dụng bất ngờ trong việc chữa trị nhiều bệnh lý quan trọng cho con người
    Sữa ong chúa bôi mặt có tác dụng gì?Sữa ong chúa tươi nguyên chất là món quà của người mẹ thiên nhiên ban tặng cho con người. Có rất nhiều công dụng cho sức khỏe và làm đẹp được mọi người tin tưởng sử dụng rất nhiều
    Sữa ong chúa tươi nguyên chất có tác dụng gì?Sữa ong chua nguyên chất là sản phẩm tinh túy nhất của ong thợ tiết ra dùng để nuôi ong.

    返信削除