1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

FlutterのDartからWebViewのJavascript関数を呼ぶのはonPageFinished以降にする

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();");
  },

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?