Android与JS交互详解

转自让Android与JS交互的详解_android js交互_低调函数的博客-CSDN博客

略微改动与拓展

一、什么是JS交互

先来说说什么是JS交互:
说的俗一点就是通过我们项目中的控件来调用HTML里的JS代码,也可以通过JS来调用项目中的代码。
Android与JS之间的桥梁就是WebView了,我们是通过WebView来实现他们的相互调用。
Android调用Js代码:
Android调用Js代码有两种方式

  • 通过WebView的loadUrl ()调用
  • 通过WebView的evaluateJavascript ()调用

Js调用Android代码:
Js调用Android代码有三种方式

  • 通过WebView的addJavascriptInterface ()进行对象映射
  • 通过WebViewClient的shouldOverrideUrlLoading()来拦截Url调用代 码
  • 通过WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()拦截JS中的对话框alert() / confirm() / prompt()

二 Android调用JS的代码

2.1 Android通过loadUrl()调用JS代码

JS写的Html:




    
    Android与Js交互


//JS的代码




在这里改变代码

布局文件:



    

    

android代码:

class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        val webview = findViewById(R.id.android_web)
            webview.settings.javaScriptEnabled = true     //设置WebView可以与JS交互 这里必须设置
            webview.settings.javaScriptCanOpenWindowsAutomatically  = true  //设置允许JS中的弹窗
            webview.loadUrl("file:///android_asset/web1.html")
        val android_btn = findViewById

在这里插入图片描述

2.2 Android通过evaluateJavascript ()调用JS代码

使用这个方法不会重新刷新webView,而loadUrl会触发刷新,且这个方法必须要在Android4.4以上才可以使用

使用方式:
1.将minSdkVersion最低版本改为19
build.gradle----minSdkVersion
2.直接替换第一种方式

webview.evaluateJavascript("javascript:clickJS()",object :
         ValueCallback {
        override fun onReceiveValue(value: String?) {
//    这里返回JS的结果
       }
})

两种方式的区别:

  • 1.loadUrl() 使用起来方便简洁。 但是他是在没有返回的情况下使用。 效率比较低,获取返回值的时候很麻烦。 并且调用的时候会刷新WebView
  • 2.evaluateJavascript () 效率比loadUrl ()高很多 虽然效率高但是只支持Android4.4以上 在获取返回值时候很方便 调用时候不刷新WebView

根据情况使用两种方式,我们可以根据当前项目开发的需求选择相应的使用方式
我们可以直接判断版本号来区分使用方式

if (Build.VERSION.SDK_INT< 18) {
  android_web.loadUrl("javascript:clickJS()")
} else {
  android_web.evaluateJavascript("javascript:clickJS()") {
    //返回JS方法中的返回值,我们没有写返回值所以为null
  }
}

三 JS调用Android代码

3.1 使用WebView的addJavascriptInterface()进行对象映射

JS代码:


Android代码:

 webview.addJavascriptInterface(JsObject(),"android")
inner class JsObject {
    @JavascriptInterface
    fun jsAndroid(msg : String){
        //点击html的Button调用Android的Toast代码
        //我这里让Toast居中显示了
        val makeText = Toast.makeText(this@MainActivity2, msg,Toast.LENGTH_LONG)
        makeText.setGravity(Gravity.CENTER,0,0)
        makeText.show()
    }
}

来看看效果图
在这里插入图片描述

3.2 使用WebViewClient ()的shouldOverrideUrlLoading ()方法拦截Url调用Android代码

使用这个方式需要定义一个协议进行拦截


 Android代码:

webview.webViewClient = MyWebViewClient()

inner class MyWebViewClient : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
//      获取Uri  这里的URL是我们在JS方法中写的URL协议"js://webview?name=zhangsan&age=20&sex=0"
      val uri = Uri.parse(url)
      if (uri.scheme == "js") {
        if (uri.authority == "webview") {
          val makeText = Toast.makeText(this@MainActivity, url, Toast.LENGTH_LONG)
          makeText.setGravity(Gravity.CENTER, 0, 0)
          makeText.show()
        }
        return true
      }
      return super.shouldOverrideUrlLoading(view, url)
    }
  }

来看一下效果

在这里插入图片描述

3.3 使用WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()拦截JS中的对话框alert() / confirm() / prompt()

JS代码:




    
    Title


欢迎光临启舰的blog

Android代码:

class MainActivity : AppCompatActivity() {

    var mWebView:WebView?=null

    inner  class MyWebChromeClient:WebChromeClient(){

        override fun onJsAlert(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("luojie","$message + $result")
            return super.onJsAlert(view, url, message, result)
        }

        override fun onJsPrompt(
            view: WebView?,
            url: String?,
            message: String?,
            defaultValue: String?,
            result: JsPromptResult?
        ): Boolean {
            Log.d("luojie","$message + $result")
            return super.onJsPrompt(view, url, message, defaultValue, result)
        }

        override fun onJsConfirm(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("luojie","$message + $result")
            return super.onJsConfirm(view, url, message, result)
        }

        override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
            Log.d("luojie","${consoleMessage?.message()}")
            return super.onConsoleMessage(consoleMessage)
        }

        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            Log.d("luojie","${newProgress}")
            super.onProgressChanged(view, newProgress)
        }


    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mWebView = findViewById(R.id.webview)
        mWebView?.settings?.javaScriptEnabled = true
        mWebView?.webViewClient = WebViewClient()
        mWebView?.webChromeClient = MyWebChromeClient()
        mWebView?.loadUrl("file:///android_asset/web.html")

    }
}

拓展:

WebViewClient与WebChromeClient的区别

Android应用开发的时候可能会用到WebView这个组件,使用过程中可能会接触到WebViewClient与WebChromeClient,那么这两个类到底有什么不同呢?

WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:

onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest

WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如

onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle

看上去他们有很多不同,实际使用的话,如果你的WebView只是用来处理一些html的页面内容,只用WebViewClient就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient。

你可能感兴趣的:(Android,android,javascript,交互)