OpenLayersをWebViewで貼り付ける

WebViewを貼り付けてJavaScriptアプリをDalvikアプリのようにみせるアプリの続き。

Leafletを使おうとして、手持ちの端末でうまくいかんかったので、OpenLayersを使うことにしました、までがこれまでのあらすじ。

しかしOpenLayersでも問題が発生。

アプリの一回目の起動は問題ないのですが、いったん閉じて(Androidではアプリを閉じてもプロセスまでは落ちない)再び開き直すと、何かうまくいかない。

コンソールを眺める

JavaScriptデバッグでは、とりあえずコンソールを見ます。が、WebViewからは通常は見えなくなっています。

WebView webView;
...
webView.setWebChromeClient(new WebChromeClient());

としてやると、コンソールログがLogCatに流れてくれるので便利です。ただし、配布アプリでWebViewのコンソールをLogCatから見られるのがイヤな場合には外しておいた方がいいように思います。

話をもどして、LogCatでコンソールを見ていると、OpenLayers側で、「wというプロパティが無い」だのなんだの言われた。

どうも Map内で this.size.w でひっかかってる模様。

遅延させてどうにかしてやろうかと画策

JavaScriptが先走っちゃってるんだろう、と。たとえば setTimeout(init,0) とかしてやると、なんとなくうまくいきました。ただしこれは標準のOpenLayers.jsでの話し。カスタムビルドして小さいスクリプトにしたったところ、setTimeout(init,0) だと失敗しました。ということは、setTimeoutの遅延期間をチューンしても、条件が違うと数字が違ってくるので、実質不可能。まあ1秒ぐらい待てばだいたいOKなんだろうけど、できればそういうのは避けたい。

clearCacheで遅延せざるをえなくする

次に考えたのは、WebView::clearCache を使うこと。onDestroyでWebViewからキャッシュを消し去ることで、2回目に開いても1回目と同じ環境であるはずだ、と。これ、意外とうまくいった、と思ったです。

しかし、次の日にはまたうまくいかなかった。前の日はうまくいってたのに。なんだよ…。

結局の回避策

初期化メソッドで、MAPを貼る対象の div を見て、clientWidth, clientHeight が正の数になったら初期化を始める、というようにしました。
とりあえずこれで動いているけれども、まだ不安ではある。