Make sure to post javascript channel messages from the platform thread. (#1429)

The Android's webview's JavascriptInterface doesn't promise to invoke
the interface's Java method on the main thread, since postMessage is
sending a message over the platform channel we need to make sure it's
doing so from the platform thread.
diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md
index 81801b8..fc34c1c 100644
--- a/packages/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.5+3
+
+* Make sure to post javascript channel messages from the platform thread.
+
 ## 0.3.5+2
 
 * Fix crash from `NavigationDelegate` on later versions of Android.
diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
index 9db7d5e..21720cf 100644
--- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
+++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
@@ -7,6 +7,7 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
+import android.os.Handler;
 import android.view.View;
 import android.webkit.WebStorage;
 import android.webkit.WebView;
@@ -25,10 +26,12 @@
   private final WebView webView;
   private final MethodChannel methodChannel;
   private final FlutterWebViewClient flutterWebViewClient;
+  private final Handler platformThreadHandler;
 
   @SuppressWarnings("unchecked")
   FlutterWebView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) {
     webView = new WebView(context);
+    platformThreadHandler = new Handler(context.getMainLooper());
     // Allow local storage.
     webView.getSettings().setDomStorageEnabled(true);
 
@@ -214,7 +217,7 @@
   private void registerJavaScriptChannelNames(List<String> channelNames) {
     for (String channelName : channelNames) {
       webView.addJavascriptInterface(
-          new JavaScriptChannel(methodChannel, channelName), channelName);
+          new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName);
     }
   }
 
diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java
index e7e76b2..180ca4f 100644
--- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java
+++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java
@@ -4,6 +4,8 @@
 
 package io.flutter.plugins.webviewflutter;
 
+import android.os.Handler;
+import android.os.Looper;
 import android.webkit.JavascriptInterface;
 import io.flutter.plugin.common.MethodChannel;
 import java.util.HashMap;
@@ -18,6 +20,7 @@
 class JavaScriptChannel {
   private final MethodChannel methodChannel;
   private final String javaScriptChannelName;
+  private final Handler platformThreadHandler;
 
   /**
    * @param methodChannel the Flutter WebView method channel to which JS messages are sent
@@ -25,18 +28,31 @@
    *     channel with each message to let the Dart code know which JavaScript channel the message
    *     was sent through
    */
-  JavaScriptChannel(MethodChannel methodChannel, String javaScriptChannelName) {
+  JavaScriptChannel(
+      MethodChannel methodChannel, String javaScriptChannelName, Handler platformThreadHandler) {
     this.methodChannel = methodChannel;
     this.javaScriptChannelName = javaScriptChannelName;
+    this.platformThreadHandler = platformThreadHandler;
   }
 
   // Suppressing unused warning as this is invoked from JavaScript.
   @SuppressWarnings("unused")
   @JavascriptInterface
-  public void postMessage(String message) {
-    HashMap<String, String> arguments = new HashMap<>();
-    arguments.put("channel", javaScriptChannelName);
-    arguments.put("message", message);
-    methodChannel.invokeMethod("javascriptChannelMessage", arguments);
+  public void postMessage(final String message) {
+    Runnable postMessageRunnable =
+        new Runnable() {
+          @Override
+          public void run() {
+            HashMap<String, String> arguments = new HashMap<>();
+            arguments.put("channel", javaScriptChannelName);
+            arguments.put("message", message);
+            methodChannel.invokeMethod("javascriptChannelMessage", arguments);
+          }
+        };
+    if (platformThreadHandler.getLooper() == Looper.getMainLooper()) {
+      postMessageRunnable.run();
+    } else {
+      platformThreadHandler.post(postMessageRunnable);
+    }
   }
 }
diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml
index db694ed..77c0ce9 100644
--- a/packages/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/pubspec.yaml
@@ -1,6 +1,6 @@
 name: webview_flutter
 description: A Flutter plugin that provides a WebView widget on Android and iOS.
-version: 0.3.5+2
+version: 0.3.5+3
 author: Flutter Team <flutter-dev@googlegroups.com>
 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter