飴屋

開発日記/2012年の日記

2012/9/7

FlexでTabNavigatorを使っていたら躓いたのでメモ。
必要に応じて利用できるようにするタブがあり、初期状態ではそのタブに関連するContainerはenabled=falseになってました。そのタブの中身の実装を済ませてテストしてみると、enabled=trueになったContainer中の要素にアクセスできないという事態が発生しました。どうもidのついた要素にアクセスしてもnullが返ってきている様子で、「nullオブジェクトの無効なメソッド名にアクセスしてるよ」と怒られる始末。

Flexは半分宣言型なのでmxmlファイルに記述した要素にはいつでもアクセスできるのだと思っていたらそういうわけではなく、処理の無駄を省くためにちゃんと必要な部分を必要に応じてメモリに展開する仕組みが備わっているようなのです。初期状態でenabled=falseなContainerだったからなのか詳細な仕様はわかりませんが、子要素が展開される前にアクセスをしたのでnullを返されたのだと思われます。

とりあえずTabNavigatorのcreationPolicyというプロパティに「ContainerCreationPolicy.ALL」を指定したところ子要素が返ってくるようになりました。メモリへの展開を何の計画もなく即座に行ってくれるという指定なので、使いどころを間違えると無駄な処理を増やすことになりそうです。

2012/8/24

Android端末向けのWEBサイトを制作中にビックリしたことのメモ。
Androidの端末は国内でもいろんなバージョンが併存する状況ですが、古いAndroidのブラウザは最近のものとは挙動が異なることがあります。今回はHTML5で新たに追加されたタグに関する問題でギョッとしました。

HTML5では文書の構造化をより明確にするためにいくつかタグの仕様が追加で策定されました。(厳密には現時点でHTML5の規格はGOがでたわけではありませんが。)
クライアントからHTML5の規格にそってサイトをコーディングする旨請け負ったので、意気揚々と(古いIEのことを気にせずに)section,aside,nav,article,menu,header,footerといったタグを散りばめて、CSS3でデコったのですが、自分のAndroid2.2端末のブラウザでOKだった内容がお客さんのAndroid2.1端末ではひどく表示が崩れると連絡をもらいました。

国内のお客さんにはAndroid端末が話題になり始めた頃の2.1端末をアップデートしないでそのまま使っている方もいらっしゃるでしょうし、対応は必須とのことで、何とかしなくてはならないなと、Android2.1端末のエミュレーターを眺めていたら、どうやら新しいタグを使ったところばかりが崩れているような気がしてきました。

Android2.1のブラウザではHTML5の新しいタグを正しく扱えず、未定義のタグと同様にブロック要素のはずがインライン要素としてレンダリングされていたようです。

menu,nav,section,aside,article,header,footer {display:block;}

こんな感じでCSSの設定を加えてあげたら正しく表示されるようになりました。よかったよかった。

余談ですが、box-sizingやbox-shadowなんかも古いAndroid端末では正規に対応していないようで、-webkit-のプリフィックスが必要でした。古いIEよりも古いAndroidが問題となる場面が今後増えるような気がしました。

2012/6/21

Adobe AIRを使ってアプリケーションを作ってみたときに陥った話のメモ。
初めてのAIRアプリということで右も左もわからない状態だったのでちょっと悩みました。

FlashDevelopからPC向けに拡張子.airのインストーラーを作成し、別のPCにインストールしようとした際に、以下のエラーメッセージが表示されてインストールが完了しませんでいた。

エラーが発生しました。
AIR ファイルが破損しているためアプリケーションをインストールできませんでした。
アプリケーション作成者に問い合わせて、新しい AIR ファイルを入手してください。

ググッた結果、アプリの署名に関する問題であるとか、アプリの生成時の作法が悪いとか、たまに起こるエラーだけどたまに起こらないよとか、いろいろ情報は出てくるも解決につながりませんでした。

インストールしようとしたパソコンX起因の問題かもしれないので、とりあえず開発元パソコンYでインストーラーを実行するとあっさりとインストールが完了したので、問題はパソコンXにあるに違いないと考えましたが、Adobe AIRのランタイムも最新版を入れてあるし、それ以上パソコンXとパソコンY間で環境の差異が見当たりません。

となると次は経路を疑ってみることにしました。パソコンXとパソコンYはネットワークでつながっており、パソコンXではパソコンYに保存されているairファイルにネットワーク越しにアクセスしてインストールを行おうとしていました。なので、airファイルをパソコンXのローカルディスクにコピーしてからインストールを再度実行することにしました。その結果、正常にインストールが完了しました。

なにかネットワークを介すると都合の悪いことがあったのでしょうかね。airファイルを配布する際に気をつけようと思いました。

2012/3/2

WordPressのテーマがあるとき突然標準の「Twenty Eleven」に変わってしまって、びっくりしたメモ。

自分以外に管理者権限でWordpressを操作できる人がいるので、その人が何かをやらかしたのかと思いましたが、その人はどうも記事を書いただけのようでした。

原因は不明でしたが、このままではまずいのでテーマを元に戻そうと管理者画面のテーマ一覧を確認すると元のテーマが一覧から姿を消していました。

誰か誤ってテーマを削除してしまったのかと思って、サーバーのテーマ保存ディレクトリを覗いてみるとファイルは存在していました。サイトのオープン前であれこれ変更が頻繁に入っているし、DNSを書き換えたりしたし、なにもかも怪しいので疑心暗鬼状態になりました。

結局、原因はシンプルで、一月ほど前にテーマの必須構成ファイルであるindex.phpを使わないからいらないと思って削除していたのが原因でした。index.phpとstyle.cssは最低限必要なので、テーマのディレクトリに入ってないとそのテーマは無効なものとなってしまうようでした。

一月前の作業が、今になって問題を起こすとか、随分と長い潜伏期間でした。テーマの有効性をチェックする処理が何かをきっかけに走ったのでしょうね。オープン前でまだよかった。

2012/1/19

バンディングの話。その昔、PCのモニタでフルカラー(16.7M色)がまだ一般的ではなかった頃、フルカラー(24bit)で作ったグラデーションをハイカラー(16bit)のモニタで眺めると、グラデーションに縞模様がはいるという現象が起こりました。これはデータ的な不備ではなく、モニタの再現力不足と人間の輪郭のコントラストを強調しようとする錯視(マッハバンドとかいう)によって起こされた現象でした。フルカラーモニタの普及と伴いこういう現象が聞かれなくなりました。

しかし、世の中に携帯電話が流行し出すと同じ事が携帯用のコンテンツでも発生しました。携帯の液晶の色数は、その計算能力や技術的な向上とともにどんどん進歩していきましたが、PCと同程度のことがそろそろできそうかなという段階でフルカラーのデータでバンディングが発生するケースが出てきました。

そして先日、スマホのコンテンツ開発にあってまたバンディングと向き合うことになりました。元々、PC用にデザインされたサイトをスマホでも見やすいように調整する作業を行っていたのですが、いくつかの画像が一部のAndroid端末で正しく描画されないという事態が発生しました。画像に発生したいくつもの縞は、過去の悪夢をよみがえらせます。

というわけで調べた結果をメモします。

現象

透過PNG(アルファチャンネル付き32bitPNG)をAndroid標準のブラウザで閲覧すると、アルファチャンネルのグラデーションに沿って縞が発生する。Androidのエミュレーターでは、OSのバージョン2.2で発生し、2.3以降では確認できなかったが、日本市場に出回っている2.3端末でも発生しているケースが一件確認された。なお、Android用Firefoxを問題の出る端末にインストールして確認したところ現象は確認されなかった。

原因

Alpha Channel Bandingなどでググッてみるも、原因に関する情報は得られなかった。そこでアルファチャンネルのグラデーションに使われている数値を数え、縞の数で割ったところ、およそアルファ値が8ごとに縞が発生しているのではないかと推測された。ひょっとしたらPNG画像のアルファ値の下位3〜4bitぐらいは計算を省かれているっていうか捨てられてるんじゃないかと予想を立てた。

対策

もしも予想が正しければ、色のバンディングのときと同じような対策が有効かもしれないので、

  1. 透明度を有効ピクセルの密度で擬似的に表す
  2. 透明度の有効値を減らして、中間値は前後の数値を混合して擬似的に表す

という作戦を立てた。
前者はPhotoshopでレイヤーをディザー合成するという単純な処理で間に合わせた。ドットが散らばるので、そんなにきれいじゃないかもしれないが、スマホで見る分にはそこそこごまかせた。

後者は操作が少しやっかいで、RGB(色情報)とA(透明度情報)を分けて、Aに対してだけ色情報でいうところの減色のような処理を行ったうえで再度元のRGBと合成した。PhotoshopでRGBとAを分離するという操作が自分にはできなかったので、渋々プログラムを書いた。ActionScriptは便利だった。減色の度合いによって縞の数が減るので、最適なものを作るのが少しやっかいだった。

32bitフルカラーのデータと比べると汚くなるのは仕方がないとして、問題のスマホ端末で見る分にはそれほど問題がなさそうだった。ただ、アルファ値の下位ビットを捨てる端末と捨てない端末を峻別する方法がなかったので、まだちょっと困ってる。

2012/1/12

Google Maps API v3を使っていてよくわからない問題が発生したときのメモ。

現象

情報ウィンドウ(google.maps.InfoWindow)がコンテンツに合わせたサイズにならず、setCenterやpanToメソッドで地図の中央を移動しようとしても指定の座標が左上にきてしまう。

原因

地図のコンテナの表示・非表示(display:block<->none)を繰り返すうちに、おそらく地図の縦横サイズが 0px x 0pxに変更され、左上が地図の中央になってしまった。

対策

//gmapはgoogle.maps.Mapクラスのインスタンス
google.maps.event.trigger(gmap, 'resize');

地図のコンテナを表示したあとに、対象の地図にリサイズイベントを強制して、地図のサイズを更新してあげると問題が解消しました。

2012/1/2

あけましておめでとうございます。

Google AppEngineの環境でPython2.7に変更した際に起こった問題についてのメモです。

現象

GAEから出力される情報の一部が何かおかしくなった模様

原因

Pythonのバージョンを2.7にしたついでに、Djangoもバージョン1.2を利用するように変更したところ、新しいDjangoではテンプレートに挿入される値を自動的にエスケープ処理してくれるようになったらしく、出力されるXMLの構造の一部がエスケープによって破壊されていた。

<hoge>
<data>{{xmldata}}</data>
</hoge>

xmldataの中のタグはエスケープされてしまうので、DOM構造が崩れる例。

対策

エスケープ処理を制御するためのフィルタ(safe)を使うか、autoescapeブロックでエスケープ処理が不要な範囲を囲む必要がある。

<hoge>
<data>{{xmldata|safe}}</data>
</hoge>

xmldataはエスケープが不要なことが事前に分かっていることをテンプレートのレンダラに伝えるフィルタ使用例。

<hoge>
{% autoescape off %}
<data>{{xmldata}}</data>
{% endautoescape %}
</hoge>

autoescapeをoffにするブロックで囲まれた値もエスケープされない。

雑感

autoescapeとか後だしされると、気楽にライブラリをアップデートできないですね。要修正な箇所を洗い出すのが大変そうです。増えるWEBアプリへの配慮なんですかね。

開発日記