JS 与 Native APP 互动示例

1. 网页端 JS 调用 Native APP 中的代码

2. Native APP 调用 JS 端的代码

3. 它们之间的数据传递如何实现

4. 代码实现效果如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8dYqUSL1-1589252279377)(https://raw.githubusercontent.com/ThornFUN/JsAndNativeAPPDemo/master/GIFResource/device-2018-07-06-225241.gif)]

  • Manifest.xml 中添加权限

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

      package com.demo.thorn.jsandnativeappdemo;
      
      import android.content.DialogInterface;
      import android.content.Intent;
      import android.support.v7.app.AlertDialog;
      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.KeyEvent;
      import android.view.View;
      import android.webkit.JavascriptInterface;
      import android.webkit.JsResult;
      import android.webkit.WebChromeClient;
      import android.webkit.WebResourceError;
      import android.webkit.WebResourceRequest;
      import android.webkit.WebSettings;
      import android.webkit.WebView;
      import android.webkit.WebViewClient;
      import android.widget.Button;
      import android.widget.Toast;
      
      public class MainActivity extends AppCompatActivity {
      
          private WebView mWebView;
          private WebSettings mWebSettings;
          private Button btnDoJS;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              btnDoJS = findViewById(R.id.btn_fun);
              mWebView = findViewById(R.id.wv_content);
              mWebSettings = mWebView.getSettings();
      
              mWebSettings.setJavaScriptEnabled(true);
              mWebSettings.setDefaultTextEncodingName("UTF-8");
              mWebView.addJavascriptInterface(this,"androidTag");//传入类对象,传入 androidTag 作为调用标志
              mWebView.setWebViewClient(new MyWebViewClient());//传入 MyWebViewClient 对象,达到接收 HTML 传递的点击动作
              mWebView.setWebChromeClient(new MyWebChromeClient());//传入 MyWebChormeClient 对象,达到对话框可用的目的
      
              mWebView.loadUrl("file:///android_asset/test.html");
      
      
              btnDoJS.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      mWebView.loadUrl("javascript:doSomething()");// Activity 中调用 JS 的方法,可以加参数传值
      
                      /* 如果调用 JS 时,需要获得返回值,则调用 evaluateJavascript 这个方法,示例如下:
                      mWebView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
                          @Override
                          public void onReceiveValue(String value) {
                              Log.e(TAG, "onReceiveValue value=" + value);
                          }
                      });
                      */
                  }
              });
          }//onCreate 结束
      
          /*HTML 中被调用的方法*/
          @JavascriptInterface
          public void showToast(String text) {
              Toast.makeText(this, text, Toast.LENGTH_LONG).show();
          }
      
          /*HTML 中被调用的方法*/
          @JavascriptInterface
          public void toAnotherAcitity(){
              Intent intent2 = new Intent(MainActivity.this,SecondActivity.class);
              startActivity(intent2);
          }
      
          /*HTML 中被调用的方法*/
          @JavascriptInterface
          public void showDialog() {
              new AlertDialog
                      .Builder(this)
                      .setTitle("Title Here")
                      .setCancelable(true)
                      .setNegativeButton("cacel", new DialogInterface.OnClickListener() {
                          @Override
                          public void onClick(DialogInterface dialogInterface, int i) {
                              showToast("negative");
                          }
                      })
                      .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                          @Override
                          public void onClick(DialogInterface dialogInterface, int i) {
                              showToast("positive");
                          }
                      })
                      .setMessage("messages here ")
                      .show();
          }
      
          private class MyWebViewClient extends WebViewClient {
      
              /*官方文档:Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView.*/
              /*在加载一个新的 URL 链接之前进行的操作(一般都是对一些 URL 进行拦截)*/
              @Override
              public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  if(url.equals("http://www.qq.com/")){
                      showToast("拦截了 QQ 网站");
                      return true;// 返回 true 表示拦截本次跳转;返回 false 表示继续跳转
                  }else if(url.endsWith("test")){
                      toAnotherAcitity();
                      return true;
                  }
                  return false;
              }
      
              /*如果加载某个页面出错,跳转到本地的一个错误展示页面*/
              @Override
              public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                  super.onReceivedError(view, request, error);
                  mWebView.loadUrl("file:///android_asset/errorPage.html");//加载本地的错误页面
                  Log.i("jin",error.toString());
              }
          }
      
          //继承 WebChromeClient 管理 JS 调用 Native APP 得事件
          public class MyWebChromeClient extends WebChromeClient {
              @Override
              public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
      
      
                  return super.onJsAlert(view, url, message, result);
              }
      
              @Override
              public void onReceivedTitle(WebView view, String title) {
                  super.onReceivedTitle(view, title);
                  Log.i("jin","title="+title.toString());
              }
          }
      
          /*用于实现网页浏览的“返回”功能*/
          @Override
          public boolean onKeyDown(int keyCode, KeyEvent event) {
      
              if(mWebView.canGoBack()&& keyCode == KeyEvent.KEYCODE_BACK){
                  mWebView.goBack();
                  return true;
              }
              return super.onKeyDown(keyCode, event);
          }
      }
    
  • activity_main.xml

      <?xml version="1.0" encoding="utf-8"?>
      <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="com.demo.thorn.jsandnativeappdemo.MainActivity">
      
          <WebView
              android:layout_weight="1"
              android:id="@+id/wv_content"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
          <Button
              android:text="这里 Activity 调用 JS"
              android:id="@+id/btn_fun"
              android:layout_width="match_parent"
              android:layout_height="50dp" />
      
      </LinearLayout>
    
  • test.html(assets\test.html)

      <html>
          <head>
              <meta charset="utf-8"/>
              <title>Js调用Android</title>
      
              </head>
          <body>
              <div>
                  <dl>
                      <dd><a href="http://www.qq.com">被拦截的URL</a></dd>
                      <dd><a href="http://www.baidu.com">正常的URL</a></dd>
                      <dd><a href="http://www.qq.test" >想在 shouldOverrideUrlLoading 中调用intent跳转,但失败了</a></dd>
                      <dd><input type="button" value="调用方法NativeAPP中的方法跳转" onclick="androidTag.toAnotherAcitity()"/></dd>
                      <dd><input type="button" value="Toast 提示" onclick="androidTag.showToast('调用了 showToast 方法');"/></dd>
                      <dd><input type="button" value="列表对话框" onclick="androidTag.showDialog();"/></dd>
                      <dd> <input type="button" value="Alert" onclick="alertSomeThing()"/></dd>
      
                      <dd><div id="content"><h2>这是初始内容</h2></div> </dd>
                  </dl>
              </div>
          </body>
          <script>
              function alertSomeThing(){
                  // 弹出一个框
                  alert("alert something to show ");
              }
      
              function doSomething(){
                  //改变 id 为 content 中的值
                       document.getElementById("content").innerHTML =("测试1111111111111");
              }
          </script>
      
      </html>
    
  • errorPage.html(assets\errorPage.html)

      <html>
          <head>
              <meta charset="utf-8"/>
              <title>ErrorPage</title>
          </head>
          <body>
              <a>不好意思,出错了哟</a>
          </body>
      </html>
    

源代码

	https://github.com/ThornFUN/JsAndNativeAPPDemo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值