Kotlin与H5通信的实现方式
Kotlin与H5通信
1、H5中主动的调用Kotlin中的程序
要知道kotlin和html是两种不同的程序,并且一个运行在手机的android端,一个运行在服务器的后端程序,让这两种不同运行环境的不同编程语言进行通信,需要用到addJavascriptInterface方法,来进行数据的访问和方法的调用
下面开始一些环境准备工作
1编写后端程序并且在服务器上运行
运行的端口是http://localhost:8080/bmi/,主要就是一个可以根据人的身高和体重计算出BMI值的小程序还有一个点击之后就可以调用kotlin程序的按钮
其中jsp文件为
<%--Created by IntelliJ IDEA.User: 26678Date: 2021/4/5Time: 16:54To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>测量BMI值</title></head><script type="text/javascript">function search() {//1var xmlHttp=new XMLHttpRequest()//2xmlHttp.onreadystatechange=function(){if(xmlHttp.readyState==4&&xmlHttp.status==200){var mess=xmlHttp.responseText;//要分开获取,先获得对象,才能给value赋值var obj=document.getElementById("dis")obj.value=messdocument.getElementById("disbim").innerHTML=mess//alert(mess)}}//3var name=document.getElementById("name").valuevar weight=document.getElementById("w").valuevar height=document.getElementById("h").valuevar message="name="+name+"&w="+weight+"&h="+heightxmlHttp.open("get","one?"+message,true)//这里面第二个数据是打开对应的服务器地址//4xmlHttp.send()}function showKotlin() {var jsonData={"name":"海航"}/*在当前窗口下使用通信桥梁来调用kotlin中的程序*/window.jsInterface.showToast(JSON.stringify(jsonData))}</script><body><table><tr><td>用户姓名</td><td><input type="text" id="name"></td></tr><tr><td>您的身高</td><td><input type="text" id="h"></td></tr><tr><td>您的体重</td><td><input type="text" id="w"></td></tr></table><br><input type="button" value="获取BMI值" onclick="search()"><br><input type="text" value="bim=" id="dis"><div id="disbim">请点击提交来显示您的bim值</div><input type="button" value="下面开始实现H5和Kotlin进行通信的学习" ><input type="button" value="点击之后调用Kotlin程序" onclick="showKotlin()"></body>
</html>
2准备好AndroidStudio的界面布局中的WebView
<WebViewandroid:id="@+id/mWebView"android:layout_width="match_parent"android:layout_height="match_parent"/>
3编写工具类用来处理H5调用逻辑
package com.njupt.kotlinandh5.jsutilimport android.content.Context
import android.webkit.JavascriptInterface
import android.widget.Toast//来处理 Kotlin与js通信的桥梁类
class JavaScriptMethods {private var mContext:Context?=nullconstructor(context:Context){this.mContext=context}//加入一个方法@JavascriptInterfacefun showToast(json:String,){mContext?.let{Toast.makeText(mContext,json,Toast.LENGTH_SHORT).show()}}}
4通过addJavascriptInterface来构建桥梁
package com.njupt.kotlinandh5import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import com.njupt.kotlinandh5.jsutil.JavaScriptMethodsclass MainActivity : AppCompatActivity() {private val myWebView by lazy {findViewById<WebView>(R.id.mWebView)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)getUrl()}private fun getUrl(){//1开启kotlin与H5通信的开关myWebView.settings.javaScriptEnabled=truemyWebView.webViewClient=MyWebViewClient()myWebView.webChromeClient=MyWebChromeClient()//2当H5与kotlin进行通信时需要使用到通信桥梁类,后面字符串参数表示前面这个参数的对象名myWebView.addJavascriptInterface(JavaScriptMethods(this),"jsInterface")myWebView.loadUrl("http://10.0.2.2:8080/bmi/")}private class MyWebViewClient:WebViewClient(){//界面加载完成之后会调用这个方法override fun onPageFinished(view: WebView?, url: String?) {super.onPageFinished(view, url)}}private class MyWebChromeClient:WebChromeClient(){//加载进度条override fun onProgressChanged(view: WebView?, newProgress: Int) {super.onProgressChanged(view, newProgress)}}
}
5结果展示
可以看到点击按钮之后,调用了JavaScriptMethods类中的showToast方法进行显示
需要注意的是当使用模拟器访问本地网页时,网址变成了10.0.2.2
2在Kotlin中调用H5的程序
1在H5中编写方法,来处理Kotlin的请求
<script>
/*模拟Kotlin来调用H5中的代码,*/var kotlinUseH5=function (json) {alert(JSON.stringify(json))}</script>
2在Kotlin中调用方法
inner private class MyWebViewClient:WebViewClient(){//界面加载完成之后会调用这个方法override fun onPageFinished(view: WebView?, url: String?) {super.onPageFinished(view, url)//第二种通信方式,在kotlin种去访问H5种的方法val json=JSONObject()json.put("name","这是Kotlin界面传来的数据")//调用的例子就是myWebView.loadUrl("javascript:方法名")myWebView.loadUrl("javascript:kotlinUseH5("+json.toString()+")")}}
3结果展示
3使用CallBack机制来实现H5中发起请求到Kotlin,然后Kotlin去 将响应的结果返回给Kotlin.
1在H5中编写发起请求和响应请求的函数
<script>function callBackM() {//1到Kotlin去加载数据var json={"callback":"receiveUserData"}window.jsInterface.getUserData(JSON.stringify(json))//2将返回的数据加载在当前界面}//用来 获取到返回的数据var receiveUserData=function (json) {alert(JSON.stringify(json))}</script>
//按钮为
<input type="button" value="点击之后使用Callback来调用Kotlin程序" onclick="callBackM()">
2编写处理请求的函数
package com.njupt.kotlinandh5.jsutilimport android.content.Context
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.widget.Toast
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import org.json.JSONObject//来处理 Kotlin与js通信的桥梁类
class JavaScriptMethods {private var mContext:Context?=nullprivate var mWebView:WebView?=nullconstructor(context:Context,webView: WebView){this.mContext=contextthis.mWebView=webView}//加入一个方法@JavascriptInterfacefun showToast(json:String,){mContext?.let{Toast.makeText(mContext,json,Toast.LENGTH_SHORT).show()}}@JavascriptInterface//使用callback机制实现调用,为了应对方法名的变化,所以使用key_Value的方式fun getUserData(json:String){var isJson=JSONObject(json)var callback=isJson.optString("callBack")//H5调用此方法去获取到数据var jsonData=JSONObject()jsonData.put("name","花木兰")jsonData.put("age","18")jsonData.put("address","中国古代")//println(jsonData.toString())//2将当前请求到的数据返回到H5mWebView?.let { it.loadUrl("javascript:"+callback+"("+jsonData.toString()+")")}}}
3主程序中
package com.njupt.kotlinandh5import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import com.njupt.kotlinandh5.jsutil.JavaScriptMethods
import org.json.JSONObjectclass MainActivity : AppCompatActivity() {private val myWebView by lazy {findViewById<WebView>(R.id.mWebView)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)getUrl()}private fun getUrl(){//1开启kotlin与H5通信的开关myWebView.settings.javaScriptEnabled=truemyWebView.webViewClient=MyWebViewClient()myWebView.webChromeClient=MyWebChromeClient()//2当H5与kotlin进行通信时需要使用到通信桥梁类,后面字符串参数表示前面这个参数的对象名//第一种通信方式,在H5中调用Kotlin的代码myWebView.addJavascriptInterface(JavaScriptMethods(this,myWebView),"jsInterface")myWebView.loadUrl("http://10.0.2.2:8080/bmi/")}private inner class MyWebViewClient:WebViewClient(){//界面加载完成之后会调用这个方法override fun onPageFinished(view: WebView?, url: String?) {super.onPageFinished(view, url)//第二种通信方式,在kotlin种去访问H5种的方法var json=JSONObject()json.put("name","这是Kotlin界面传来的数据")//调用的例子就是myWebView.loadUrl("javascript:方法名")myWebView.loadUrl("javascript:kotlinUseH5(" + json.toString() + ")")}}private class MyWebChromeClient:WebChromeClient(){//加载进度条override fun onProgressChanged(view: WebView?, newProgress: Int) {super.onProgressChanged(view, newProgress)}}
}