20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ABC2013Spring: HTML5におけるAndroid端末間互換性

Last updated at Posted at 2013-03-15

ABC2013Sprint の講演HTML5におけるAndroid端末間互換性のまとめです.

走り書きなので, 誤字脱字はあるかもしれないが, 指摘があり次第随時修正します.

Canvas vs CSS3

CSS3

  • わずかな記法でリッチな表現が可能
  • DOMの操作をベースとした記述が主体.
  • デザイナー向け.
  • Canvasに比べ, 仕様が極めて複雑かつ曖昧, iPhone/Android間に互換性が少ない.
  • 同じOS同士のレガシーブラウザでも端末間で挙動が大きく違う.

Canvas

  • わずかな表現に相当の記述が必要.
  • ピクセル単位の操作が主体.
  • プログラマー向け.
  • 構文の解釈の違いによる互換性の問題は少ない. アンチエイリアシングの有無程度.
  • 問題になるのは, レガシーブラウザ自体のバグ/端末特有のバグ/チップセット特有のバグ(GPU, コア, etc. Intelチップ端末)

よくあるトラブル集

getImageData/putImageData

  • Canvasのピクセル情報を直接操作するAPI
  • 透明ピクセル(半透明ピクセル)があった場合に破綻する. getImageDetaで取得するデータは正しいが, putImageDataでα値をセットすると描画が破綻する.
  • セットする場合には, 乗算済みαを設定する必要がある.

Canvas#clip

  • 一部の領域だけをマスクして, その部分に描画するAPI.
  • クリッピング指定しているが, クリッピングされない. たまにクリッピングされることもある. ブラウザのバグ.
  • 描画の前後にCanvas#save()/canvas#restore()を無意味に指定すると解決する.

描画する際になぜか画面がclearRectされる.

  • Android3.0系列の某端末で発生
  • setTimeoutを利用して描画しようとすると, なぜか今までCanvasに買い得てあった秒がを全部消してしまう.
  • 描画前にCanvas#getPixelDataを無駄に呼ぶ.
  • ctx.getPixelData(0, 0, 1, 1)

画像のonloadが呼ばれない

  • Android2.2系列の某端末で発生
  • onloadする直前にsetTimeoutを無駄に呼ぶ
  • setTimeout(function(){}, 0);
  • デバッガを起動すると正しく動くのでデバッグできない.

Canvas#drawImage 画像を描画しようとすると空白になる

  • Androidの様々な端末で発生
  • たまに発生する. 負荷が高まったときなど.
  • メモリ不足が原因のはずが多いのでメモリ管理をしっかりする.
  • adb shell 'dumpsys meminfo _package-name_'

本体温度があがると描画が乱れる

  • Android4.x系の某端末で発生
  • 本体温度があがるとまれに描画が破綻する. 描画されるべき命令がスキップされ, されるべき描画がまれにされなくなる.
  • CPUに負荷がかかりすぎないように負荷を調整.

問題に対する解決方法

発見方法

  • たいていの問題は実際の端末で動かすまでは分からない. 人海戦術, サポートからの問い合わせで対応.
  • 発生した問題に対して, 似たような端末での動作を疑う. メーカー/シリーズ, Androidバージョン, メモリ搭載量, CPU(シングルコアか否か), GPU.

解決方法

  • 一般的な方法(デバッガーで1行ずつ追って見る, 頭の中での想像など)はAndroidのバグの解決方法には適していない.
  • 問題が発生する最小サンプルを作成したあと, 回避するコードをひたすら試す.
  • 基本的な動作を疑う.
  • ctx.clip(), ctx.transform() あたりをコメントアウトして確認する.
  • ctx.save(), ctx.restore() で全体を括ってみる.
  • ctx.drawImage() の再現に失敗する場合はメモリを消費させる.

回避コード

回避コードは, 全てのANdroidで動作するものが望ましい.

  • UserAgentを確認して分岐させる方法は最低のアイディア. 将来のブラウザにも対応するのが望ましい.
  • ほとんどコストを発生させずに解決するのが望ましい.
  • 回避コードには, 詳しくコメントを書く.

可能であれば

ブラウザのソースコードを一度読んでみるとよい.

  • 端末ごとの問題はソースコードが公開されていないので, ソースコードから問題の特定は不可能.
  • display object.
  • WebKit系でなくても, Mozillaでもかまわない. 特にレンダリング周りのコードがよい.

エンジニアが互換性に文句を言うのは大切だが, ユーザに快適にサービスを使ってもらう方がより大切

20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?