Flutter始めたばかりで「FlutterのDartからWebViewへ画像を送るにはData URIを使う」という記事を書きましたが、その後、注意した方がいいことに気づいたので書きます。
以下のサンプルはDartでHtmlを作成してWebViewを表示し、そこにDartから画像を転送するものです。WebView 構築時のonWebViewCreated:パラメータで指定するコールバックの中で処理されます。
// まずHtmlを作成
String html = "<html><head><script>"+
"function putimg(id,src){document.getElementById(id).src=src;}"+
"function test(){alert('test');}</script></head><body>"+
"<img id='i00'></body></html>";
// HtmlをData URIに変換してサーバー経由しないで取得できるようにする
final fileurl = Uri.dataFromString(
html, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')
).toString();
// それをWebViewで表示
webviewcontroller.loadUrl( fileurl );
// 画像をダウンロードし、Data URIでWebViewに転送
http.get(Uri.parse('http://example.com/test.jpg')).then((response) {
var dataurl = Uri.dataFromBytes(response.bodyBytes, mimeType: 'image/jpeg').toString();
webviewcontroller.evaluateJavascript("putimg('"+ item['id'] +"','"+ dataurl +"');");
});
webviewcontroller.evaluateJavascript("test();");
WebViewで表示されるHtmlには、イメージ表示用のputimg(id,src)関数と、テスト用のtest()関数が定義されています。ところが実際にコーディングして実行してみると、putimg(id,src)は動作してimgタグに画像が表示されますが、test()ルーチンは以下のようなエラーになることがあります。
I/chromium( 7851): [INFO:CONSOLE(1)] "Uncaught ReferenceError: test is not defined", source: (1)
何度かくり返していると、タイミングによってはputimg()まで同じエラーになったりします。
これはwebviewcontroller.loadUrl( fileurl );の実行が終わらないうちに、evaluateJavascriptがコールされたので、Html内に対象の関数が見つからなかったからです。text()はエラーになるがputimg()がエラーにならないのは、putimg()はhttp.getの終了を待ってからコールされるので、そのころはwebviewcontroller.loadUrl()の実行が完了しているからでしょう。
ではどうすればいいかというと、onWebViewCreated:ではなく、onPageFinished:のタイミングで呼べばいいとマニュアルに書いてありました。
Androidでは描画が終わってない可能性がありますが、Html内に埋め込まれたJavascriptは存在しているので、evaluateJavascriptでコールしても大丈夫ということです。
onPageFinished: (String url) {
http.get(Uri.parse('http://example.com/test.jpg')).then((response) {
var dataurl = Uri.dataFromBytes(response.bodyBytes, mimeType: 'image/jpeg').toString();
webviewcontroller.evaluateJavascript("putimg('"+ item['id'] +"','"+ dataurl +"');");
});
webviewcontroller.evaluateJavascript("test();");
},