天天看點

Kotlin語言 Android與JS互動

先來說說什麼是JS互動:

說的俗一點就是通過我們項目中的控件來調用HTML裡的JS代碼,也可以通過JS來調用項目中的代碼。

Android與JS之間的橋梁就是WebView了,我們是通過WebView來實作他們的互相調用。

Android調用Js代碼:

Android調用Js代碼有兩種方式

1)通過WebView的loadUrl ()調用

2)通過WebView的evaluateJavascript ()調用

Js調用Android代碼:

Js調用Android代碼有三種方式

1)通過WebView的addJavascriptInterface ()進行對象映射

2)通過WebViewClient的shouldOverrideUrlLoading()來攔截Url調用代

3)通過WebChromeClient 的onJsAlert()、onJsConfirm()、

onJsPrompt()攔截JS中的對話框alert() / confirm() / prompt()

用Kotlin實作Android與JS互動

一、Android通過 loadUrl ()調用JS代碼

1.把需要調用的JS代碼以.Html的格式放到src/main/assets檔案夾中,沒有的建立一個

<html>
  <head>
    <meta charset="utf-8" />
    <title>Android與Js互動</title>
  </head>
<body>
           //JS的代碼
    <script type="text/javascript">
          //無參方法
        function clickJS(){
            document.getElementById("zi").innerHTML = "Android調用了JS代碼"
        }
         //有參方法
        function clickJSTwo(x){
            document.getElementById("zi").innerHTML = x
        }
    //與Android互動的方法 
        function clickAndroid(){
            var result = prompt("js://webview?arg1=111&arg2=222")
            alert("demo" + result)
        }
    </script>

    <button type="button" onclick="clickAndroid()">我是一個按鈕</button>

    <p id="zi">在這裡改變代碼</p>

     </body>
</html>
                

2.在Android中用WebView調用Js代碼

//activity_main.xml布局檔案

<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">

    <TextView
        android:id="@+id/android_js"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <Button
        android:text="調用JS代碼"
        android:id="@+id/android_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <WebView
        android:id="@+id/android_web"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </WebView>
</LinearLayout>
           

//MainActivity.kt

class MainActivity : AppCompatActivity() {
private var androidText : TextView? = null
private var androidBtn : Button? = null
private var androidWeb : WebView? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
//        初始化控件
androidText = findViewById(R.id.android_text)
    androidBtn = findViewById(R.id.android_btn)
    androidWeb = findViewById(R.id.android_web)

    val settings = androidWeb!!.settings

//        設定WebView可以與JS互動 這裡必須設定
    settings!!.javaScriptEnabled = true
//        設定允許JS中的彈窗
    settings!!.javaScriptCanOpenWindowsAutomatically = true

//        然後加載JS代碼
    androidWeb!!.loadUrl("file:///android_asset/index.html")
//        調用JS無參方法
    androidBtn!!.setOnClickListener({
        androidWeb!!.post {
            run {
                //第一種方法 通過loadUrl調用JS代碼
                //調用無參JS方法
                androidWeb!!.loadUrl("javascript:clickJS()")
                //調用有參JS方法
               // androidWeb!!.loadUrl("javascript:clickJS("+"我調用了JS的方法"+")")
            }
        }
    })
  }
}
                
Kotlin語言 Android與JS互動

富江原創.gif

Android通過evaluateJavascript ()調用JS代碼

先來說說使用這個方法的優點

使用這個方法不會重新整理頁面,如果使用第一種方法則會重新整理頁面
 *注意 這個方法隻能在Android4.4之後使用
                

使用方式

1.将minSdkVersion最低版本改為19

build.gradle----minSdkVersion

2.直接替換第一種方式

androidWeb!!.evaluateJavascript("javascript:clickJS()",object : ValueCallback<String>{
                    override fun onReceiveValue(value: String?) {
//                            這裡傳回JS的結果
                    }
                })
                

兩種方式的差別

1.loadUrl() 
 使用起來友善簡潔。
 但是他是在沒有傳回的情況下使用。
 效率比較低,擷取傳回值的時候很麻煩。
 并且調用的時候會重新整理WebView

2.evaluateJavascript ()
 效率比loadUrl ()高很多
 雖然效率高但是隻支援Android4.4以上
 在擷取傳回值時候很友善
 調用時候不重新整理WebView
                

根據情況使用兩種方式

我們可以根據目前項目開發的需求選擇相應的使用方式

我們可以直接判斷版本号來區分使用方式

if (Build.VERSION.SDK_INT< ) {
  androidWeb!!.loadUrl("javascript:clickJS()")
} else {
  androidWeb!!.evaluateJavascript("javascript:clickJS()", object : ValueCallback<String> {
      override fun onReceiveValue(value: String?) {
      //傳回JS方法中的傳回值,我們沒有寫傳回值是以為null
      }
   })
}
                

二、JS調用Android代碼

1.使用WebView的addJavascriptInterface()進行對象映射

androidWeb!!.addJavascriptInterface(object : Object(){
        @JavascriptInterface
        fun jsAndroid(msg : String){
          //點選html的Button調用Android的Toast代碼  
        //我這裡讓Toast居中顯示了
            val makeText = Toast.makeText(this@MainActivity, msg,Toast.LENGTH_LONG)
            makeText.setGravity(Gravity.CENTER,,)
            makeText.show()
        }
      //第二個參數可以自己随便設定,在html裡會用到
    },"androids")
                

2.JS的方法

<script type="text/javascript">
    function clickAndroid(){
        //用androids.調用映射的對象    這裡的androids是addJavascriptInterface()的第二個參數
        androids.jsAndroid("我是JS,我調用了Android的方法")
    }
</script>
           

來看看效果圖

Kotlin語言 Android與JS互動

富江原創3.gif

2.使用WebViewClient ()的shouldOverrideUrlLoading ()方法攔截Url調用Android代碼

使用這個方式需要定義一個協定進行攔截

<script type="text/javascript">
    function clickAndroid(){
        //定義url協定
        document.location = "js://webview?name=zhangsan&age=20&sex=0"
    }   
</script>
           

代碼中這樣寫

androidWeb!!.webViewClient = object : WebViewClient(){
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
//      擷取Uri  這裡的URL是我們在JS方法中寫的URL協定"js://webview?name=zhangsan&age=20&sex=0"
       var 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,,)
                  makeText.show()
                }
                return true
            }
            return super.shouldOverrideUrlLoading(view, url)
        }
    }
                

來看一下效果

Kotlin語言 Android與JS互動

富江原創4.gif

3.使用WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()攔截JS中的對話框alert() / confirm() / prompt()

<script type="text/javascript">
        function clickAndroid(){
            // 定義一個帶輸入框的彈窗
            var x = prompt("我又調用了Android的方法");
            alert("我是JS"+x)
        }
</script>
           

Android代碼

androidWeb!!.webChromeClient = object : WebChromeClient(){
    override fun onJsPrompt(view: WebView?, url: String?, message: String?, defaultValue: String?, result: JsPromptResult?): Boolean {
        val makeText = Toast.makeText(this@MainActivity, message, Toast.LENGTH_LONG)
        makeText!!.setGravity(Gravity.CENTER,,)
        makeText.show()
        return super.onJsPrompt(view, url, message, defaultValue, result)
    }
}
                

效果圖

Kotlin語言 Android與JS互動

富江原創5.gif

三種差別

1)addJavascriptInterface ()使用起來友善簡潔,但是再Android低版本下有問題,用于Android4.4以上

2)shouldOverrideUrlLoading ()使用起來沒有漏洞,但是使用起來比較負責,主要用于不需要傳回值的情況

3)onJsAlert()、onJsConfirm()、onJsPrompt()攔截JS中的對話框alert() / confirm() / prompt()

和第二種方式一樣,沒有漏洞,而且也複雜,并且需要協定來規定他。

作者:富江_ed13

連結:https://www.jianshu.com/p/826a39ed81e6

來源:簡書

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。