当前位置: 首页>编程语言>正文

java kotlin 混合开发 无法引用 kotlin调用js

第十章 kotlin与H5混合开发



文章目录

  • 第十章 kotlin与H5混合开发
  • 前言
  • 一、Kotlin与H5通信方式一(H5主动)
  • 1.H5调用Kotlin方法
  • 二、Kotlin与H5通信方式二(Kotlin主动)
  • 1.Kotlin调用H5方法
  • 三、Kotlin与H5通信方式三(callback)
  • 1.示例1
  • 2.示例2
  • 四、Kotlin与H5通信-完整代码
  • 1.Kotlin与H5通信-完整代码
  • 总结



前言

kotlin与H5混合开发。


一、Kotlin与H5通信方式一(H5主动)

1.H5调用Kotlin方法

H5调用Kotlin方法

<script>
	$("#btn").on("click",function(){
		console.log("点击了");
		//调用Kotlin方法
		//对象.方法名(参数)
		var json = {"name":"html5"}
		window.jsInterface.showToast(JSON.stringify(json));			
	});
</script>
@JavascriptInterface //安卓4.2以后,不加上@JavascriptInterface,H5不能调用kotlin方法
    fun showToast(json:String){
        //Toast.makeText(mContext,json,Toast.LENGTH_SHORT).show() //Toast方法1

        mContext?.let { it.toast(json) } //Toast方法2
    }

二、Kotlin与H5通信方式二(Kotlin主动)

1.Kotlin调用H5方法

Kotlin调用H5方法

private inner class MyWebViewClient : WebViewClient() {
        //页面加载完成调用
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            var json = JSONObject()
            json.put("name","Kotlin")
            mWebView.loadUrl("javascript:showMessage($json)") //Kotlin与H5通信方式二(Kotlin主动)

        }
    }
<script>
	var showMessage = function(json){
		alert(JSON.stringify(json));
	};
</script>

三、Kotlin与H5通信方式三(callback)

H5 callback调用kotlin方法:H5通知Kotlin获取数据,然后Kotlin回传数据给H5

1.示例1

代码:

<script>
	<!-- Kotlin与H5通信方式三(callback) -->
	//H5 callback调用kotlin方法
	$(btn2).on("click",function(){
		//callback:1.调用kotlin方法
		console.log("callback调用");
		window.jsInterface.getStudentData();
	});
	
	var receiveStudentData = function(json){
		alert(JSON.stringify(json));
	};
</script>
@JavascriptInterface
    fun getStudentData(){
//        println("获取学生数据")
        //异步操作,子线程请求服务器
        doAsync {
            var url = URL("http://192.168.0.103:8080/Test1/student.json")
            //变成字符串
            val result = url.readText()
            println("获取学生数据="+result)
            //callback步骤2:回传数据给H5
            //调用js方法必须在主线程
            mContext?.let {
                it.runOnUiThread {
                    mWebView?.let {
//                      it.loadUrl("javascript:receiveStudentData("+result+")")
                        it.loadUrl("javascript:receiveStudentData($result)")
                    }
                }
            }
        }
    }

2.示例2

代码:

<script>
	<!-- Kotlin与H5通信方式三(callback) -->
	//H5 callback调用kotlin方法:H5通知Kotlin获取数据,然后Kotlin回传数据给H5
	//调用kotlin方法获取学生数据
	$(btn3).on("click",function(){
		//callback:1.调用kotlin方法
		console.log("callback调用");
		var json = {"callback":"receiveStudentData2"};//设置回调方法名称
		window.jsInterface.getStudentData2(JSON.stringify(json));
	});
</script>
/**
     * Kotlin与H5通信方式三(callback)
     */
    @JavascriptInterface
    fun getStudentData2(json:String){
        var jsJson = JSONObject(json)
        var callback = jsJson.optString("callback")
        //异步操作,子线程请求服务器
        doAsync {
            var url = URL("http://192.168.0.103:8080/Test1/student.json")
            //变成字符串
            val result = url.readText()
            println("获取学生数据="+result)
            //callback步骤2:回传数据给H5
            //调用js方法必须在主线程
//            mContext?.let {
//                it.runOnUiThread {
//                    mWebView?.let {
//                        it.loadUrl("javascript:$callback($result)")
//                    }
//                }
//            }
            callbackJavaScript(callback, result)
        }
    }

    /**
     * 统一管理所有kotlin回调js方法
     */
    private fun callbackJavaScript(callback: String?, result: String) {
        mContext?.let {
            it.runOnUiThread {
                mWebView?.let {
                    it.loadUrl("javascript:$callback($result)")
                }
            }
        }
    }

四、Kotlin与H5通信-完整代码

1.Kotlin与H5通信-完整代码

Kotlin与H5通信-完整代码

\webapps\Test1\indexForJSAndKotlin.html

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>test For JS And Kotlin</title>
	<SCRIPT src="js/jquery-1.9.1.min.js" type=text/javascript></SCRIPT>
</head>

<body>
<br/>
	<div> H5网页区域:</div>
	<input type="button" value="H5调用Kotlin方法" id="btn" />
	<input type="button" value="H5 callback调用kotlin方法" id="btn2" />
	<br/><br/>
	<input type="button" value="H5 callback调用kotlin方法2" id="btn3" />
	<br/><br/>
	<div id="wrapper" style="background-color:white"/>


<!-- Kotlin与H5通信方式一(H5主动) -->
<script>
	<!--  点击事件-方法1: $("#btn").click(function(){  -->
	<!--  点击事件-方法2: $("#btn").on("click",function(){  -->
	$("#btn").on("click",function(){
		console.log("点击了");
		//调用Kotlin方法
		//对象.方法名(参数)
		var json = {"name":"html5"}
		window.jsInterface.showToast(JSON.stringify(json));			
	});
	
	var showMessage = function(json){
		alert(JSON.stringify(json));
	};
	
	<!-- Kotlin与H5通信方式三(callback) -->
	//H5 callback调用kotlin方法
	$(btn2).on("click",function(){
		//callback:1.调用kotlin方法
		console.log("callback调用");
		window.jsInterface.getStudentData();
	});
	
	var receiveStudentData = function(json){
		alert(JSON.stringify(json));
	};
	
	
	
	<!-- Kotlin与H5通信方式三(callback) -->
	//H5 callback调用kotlin方法:H5通知Kotlin获取数据,然后Kotlin回传数据给H5
	//调用kotlin方法获取学生数据
	$(btn3).on("click",function(){
		//callback:1.调用kotlin方法
		console.log("callback调用");
		var json = {"callback":"receiveStudentData2"};//设置回调方法名称
		window.jsInterface.getStudentData2(JSON.stringify(json));
	});
	
	/**
	 * H5在线模板刷新数据
	 * 
	 * 接收kotlin回传的学生数据
	 * @param json
	 */
	var receiveStudentData2 = function(json){
		//alert(JSON.stringify(json));
		//解析,设置到页面中
		var nameText = '<section id="studentName" class="studentName"><div><span>学生姓名:</span><i>'+json.name+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var genderText = '<section id="gender"><div><span>性别:</span><i>'+json.gender+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var ageText = '<section id="age"><div><span>年龄:</span><i>'+json.age+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var heightText = '<section id="height"><div><span>身高:</span><i>'+json.height+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var cityText = '<section id="city"><div><span>城市:</span><i>'+json.city+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var weightText = '<section id="weight"><div><span>体重:</span><i>'+json.weight+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var phoneText = '<section id="phone" class="phone"><div><span>电话:</span><i>'+json.phone+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var classText = '<section id="class"><div><span>班级:</span><i>'+json.class+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
		var InterestText = '<section id="Interest"><div><span>兴趣爱好:</span><i>'+json.Interest+'</i></div><div style="background-color:#F5F5F5"><br></div> </section>';
			
		//动态刷新数据:
		$("#wrapper").html(nameText+genderText+ageText+heightText+cityText+weightText+phoneText+classText+InterestText);
		
		$(".phone").on("click",function(){
			//调用kotlin方法		
			console.log("调用kotlin方法");			
			window.jsInterface.showPhoneDialog(json.phone);
		});
	};
	
	
	
</script>

</body>
</html>

\webapps\Test1\student.json

{
    "status":"success",
	"gender":"男",
	"name":"张三",
	"age":"20",
	"height":"180厘米",
	"city":"北京市",
	"weight":"60公斤",
	"phone":"10086",
	"class":"2班",
	"Interest":"篮球"
}

\app\src\main\java\com\example\testkotlin1\WebTestActivity.kt

import android.os.Bundle
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_web_test.*
import org.jetbrains.anko.sdk27.coroutines.onClick
import org.json.JSONObject

/**
 * Kotlin与H5混合开发练习-知识点:
 *
 * Kotlin与H5通信的三种方式
 * H5 callback调用Kotlin
 * 本地模板动态刷新页面
 * 自定义Kotlin与H5通信接口协议
 */
class WebTestActivity : AppCompatActivity() {
    //懒加载:使用了才初始化
    private val mWebView: WebView by lazy {
        webview
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_web_test)

        tv_title.setText("测试") //直接写View的id(tv_title)即可
        //button.onClick { }

        setWebView()
    }

    //lambda表达式-示例
    //var add = {a:Int,b:Int -> a + b}

    var setWebView = {
        //1.开启Kotlin与H5通信开关
        mWebView.settings.javaScriptEnabled = true
        //2.设置2个WebViewClient
        mWebView.webViewClient = MyWebViewClient()
        mWebView.webChromeClient = MyWebChromeClient()
        //Kotlin与H5通信方式1:H5调用Kotlin方法
        //设置Kotlin与H5通信桥梁类
        //mWebView.addJavascriptInterface(对象,字符串):对象.方法名,   字符串:就是参数1对象的别名
        mWebView.addJavascriptInterface(JavaScriptMethods(this,mWebView),"jsInterface")

        //3.加载网页:在线模板,便于调试
//        mWebView.loadUrl("http://192.168.0.103:8080/Test1/indexForJSAndKotlin.html")

        //本地模板:网页保存到assets目录,提高加载速率
        mWebView.loadUrl("file:///android_asset/kotlin/indexForJSAndKotlin.html")
    }

    private inner class MyWebViewClient : WebViewClient() {
        //页面加载完成调用
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            //Kotlin与H5通信方式2:Kotlin调用H5方法
            //mWebView.loadUrl("javascript:方法名(参数)")
            var json = JSONObject()
            json.put("name","Kotlin")
//            mWebView.loadUrl("javascript:showMessage("+json.toString()+")")//方法1
            mWebView.loadUrl("javascript:showMessage($json)")//方法2 //Kotlin与H5通信方式二(Kotlin主动)

        }
    }

    private class MyWebChromeClient : WebChromeClient() {
        //加载进度条

    }
}

\app\src\main\java\com\example\testkotlin1\JavaScriptMethods.kt

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.webkit.JavascriptInterface
import android.webkit.WebView
import org.jetbrains.anko.alert
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.runOnUiThread
import org.jetbrains.anko.toast
import org.json.JSONObject
import java.net.URL

/**
 * Kotlin与H5通信桥梁类
 */
class JavaScriptMethods {
    private var mContext: Context? = null
    private var mWebView: WebView? = null

    constructor(context: Context?){
        this.mContext = context
    }
    constructor(context: Context?,webView: WebView){
        this.mContext = context
        this.mWebView = webView
    }

    @JavascriptInterface //安卓4.2以后,不加上@JavascriptInterface,H5不能调用kotlin方法
    fun showToast(json:String){
        //Toast.makeText(mContext,json,Toast.LENGTH_SHORT).show() //方法1
//        mContext?.toast(json)
        mContext?.let { it.toast(json) }  //方法2
    }

    /**
     * Kotlin与H5通信方式三(callback)
     */
    @JavascriptInterface
    fun getStudentData(){
//        println("获取学生数据")
        //异步操作,子线程请求服务器
        doAsync {
            var url = URL("http://192.168.0.103:8080/Test1/student.json")
            //变成字符串
            val result = url.readText()
            println("获取学生数据="+result)
            //callback步骤2:回传数据给H5
            //调用js方法必须在主线程
            mContext?.let {
                it.runOnUiThread {
                    mWebView?.let {
//                      it.loadUrl("javascript:receiveStudentData("+result+")")
                        it.loadUrl("javascript:receiveStudentData($result)")
                    }
                }
            }
        }
    }

    /**
     * Kotlin与H5通信方式三(callback)
     */
    @JavascriptInterface
    fun getStudentData2(json:String){
        var jsJson = JSONObject(json)
        var callback = jsJson.optString("callback")
        //异步操作,子线程请求服务器
        doAsync {
            var url = URL("http://192.168.0.103:8080/Test1/student.json")
            //变成字符串
            val result = url.readText()
            println("获取学生数据="+result)
            //callback步骤2:回传数据给H5
            //调用js方法必须在主线程
//            mContext?.let {
//                it.runOnUiThread {
//                    mWebView?.let {
//                        it.loadUrl("javascript:$callback($result)")
//                    }
//                }
//            }
            callbackJavaScript(callback, result)
        }
    }

    /**
     * 统一管理所有kotlin回调js方法
     */
    private fun callbackJavaScript(callback: String?, result: String) {
        mContext?.let {
            it.runOnUiThread {
                mWebView?.let {
                    it.loadUrl("javascript:$callback($result)")
                }
            }
        }
    }

    //底部弹出拨号对话框
    @JavascriptInterface
    fun showPhoneDialog(phone:String){
        println("js传递="+phone)
        //设置号码到对话框
        mContext?.let {
            it.alert("你要拨打电话${phone}吗?", "拨打电话") {
                positiveButton("ok" ) {
                    mContext?.let { callPhone(phone) }
                }
                negativeButton("cancel") {
                }
            }.show()
        }

    }

    /**
     * lambda表达式:调用系统拨号功能
     */
    var callPhone = {
        //phone:String -> Unit
        phone:String ->

        var intent = Intent()
        intent.action = "android.intent.action.VIEW"
        intent.action = "android.intent.action.DIAL"
        intent.addCategory("android.intent.category.DEFAULT")
        intent.addCategory("android.intent.category.BROWSABLE")
        intent.setData(Uri.parse("tel:"+phone))
        mContext?.let { it.startActivity(intent) }

    }

}

\app\src\main\res\layout\activity_web_test.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Hello World!"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <!--<Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="js调用Kotlin方法"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />-->

    <!--<Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="js调用Kotlin方法(callback)"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.501"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />-->

    <WebView
        android:id="@+id/webview"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

\app\src\main\AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testkotlin1">

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TestKotlin1"
        android:usesCleartextTraffic="true">
        <activity android:name=".WebTestActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

本地模板 - 网页保存到assets目录,提高加载速率:

java kotlin 混合开发 无法引用 kotlin调用js,java kotlin 混合开发 无法引用 kotlin调用js_kotlin,第1张

APP截屏:

java kotlin 混合开发 无法引用 kotlin调用js,java kotlin 混合开发 无法引用 kotlin调用js_H5_02,第2张


总结

以上就是今天要讲的内容,本文仅仅简单介绍了kotlin与H5混合开发知识。



https://www.xamrdz.com/lan/54q1963240.html

相关文章: