Android WebView 与Js交互,混合开发基础

2022-02-22 13:58:17 浏览数 (1)

混合开发是流行的趋势,混合开发优点

  • 支持设备广泛;
  • 较低的开发成本;
  • 可即时上线;
  • 无内容限制;
  • 用户能够直接使用最新版本号(自己主动更新,不需用户手动更新)。

好了,现在我们开始学习Android混合开发的基础,WebView如何与JS交互

首先我们看下整体的文件结构 适合新手好理解

首先我们介绍 MyWebChromeClient 继承 WebChromeClient

WebChromeClient:当影响【浏览器】的事件到来时,就会通过WebChromeClient中的方法回调通知用法。

实现代码 :

代码语言:javascript复制
public class MyWebChromeClient extends WebChromeClient {
    Context context;

    public MyWebChromeClient(Context context) {
        this.context = context;
    }

    @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);

    }

    @Override
    public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
        return super.onJsConfirm(view, url, message, result);

    }

    @Override
    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
        return super.onConsoleMessage(consoleMessage);

    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);

    }
}

继承 WebChromeClient 可重写方法来实现我们想要的效果

MyWebClient 继承 WebViewClient

WebViewClient:在影响【View】的事件到来时,会通过WebViewClient中的方法回调通知用户

代码 :

代码语言:javascript复制
public class MyWebClient  extends WebViewClient {
    private WebView webView;
    private Context context;

    public MyWebClient(WebView webView, Context context) {
        super();
        this.webView = webView;
        this.context = context;
    }

    public MyWebClient(WebView webView) {
        super();
        this.webView = webView;
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        webView.loadUrl(url);
        return true;
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
    }

    @Override
    public void onLoadResource(WebView view, String url) {
        super.onLoadResource(view, url);
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        super.onReceivedSslError(view, handler, error);

    }
}

同样是继承 WebViewClient 可重写方法来实现我们想要的效果

下面我们来看看这些方法 具体的用处

WebChromeClient

  • onJsAlert 当网页调用alert()来弹出alert弹出框前回调,用以拦截alert()函数
  • onReceivedTitle 获取网页title标题
  • onJsConfirm 当网页调用confirm()来弹出confirm弹出框前回调,用以拦截confirm()函数
  • onConsoleMessage 打印 console 信息
  • onProgressChanged 通知程序当前页面加载进度

WebViewClient

  • shouldOverrideUrlLoading 拦截页面加载,返回true表示宿主app拦截并处理了该url,否则返回false由当前WebView处理
  • onPageStarted 页面(url)开始加载
  • onPageFinished 页面(url)完成加载
  • onLoadResource 将要加载资源(url)
  • onReceivedSslError 加载资源时发生了一个SSL错误,应用必需响应(继续请求或取消请求)

这里只是简单介绍了几个常用的方法 更详细的方法介绍自行查看API

接下来就是我们主要的代码了 ,前面写了这么多东西如何使用呢 ?

上代码:

代码语言:javascript复制
public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @SuppressLint("AddJavascriptInterface")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.loadUrl("javascript:getData('我是Android端的信息')");
            }
        });
        webView = findViewById(R.id.web);
        wsetting();
        MyWebClient myWebClient=new MyWebClient(webView,getApplicationContext());
        webView.setWebViewClient(myWebClient);
        MyWebChromeClient myWebChromeClient=new MyWebChromeClient(getApplicationContext());
        webView.setWebChromeClient(myWebChromeClient);
        webView.loadUrl("file:///android_asset/test.html");
        webView.addJavascriptInterface(new jsin(getApplicationContext()),"pp");
    }
    class  jsin{
        Context context;

        public jsin(Context context) {
            this.context = context;
        }
        @JavascriptInterface
        public  void  show(){
            Toast.makeText(context, "这是html点击的", Toast.LENGTH_SHORT).show();
        }
    }
    private void wsetting() {
        //声明WebStting子类
        WebSettings webSettings=webView.getSettings();
        //开启js交互
        webSettings.setJavaScriptEnabled(true);
        //加载html里js在执行动画等操作,会造成资源浪费
        //在onStop和onResume里分别把 setJavaScriptEnabled设置成false和true即可;
        //设置自适应屏幕,两者互用
        webSettings.setUseWideViewPort(true); //将图片调整至webview的大小
        webSettings.setLoadWithOverviewMode(true);//缩放至屏幕的大小
        //缩放操作
        webSettings.setSupportZoom(true);  //支持缩放   是下面那个的前提
        webSettings.setBuiltInZoomControls(true);//设置内置的缩放控件,若为false 则该webview不可缩放
        webSettings.setDisplayZoomControls(false);//、隐藏原生的缩放控件
        //其他细节操作
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//关闭webview中的缓存
        webSettings.setAllowFileAccess(true); //设置可以访问文件
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);//支持通过js打开新的窗口
        webSettings.setLoadsImagesAutomatically(true); //自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode==KeyEvent.KEYCODE_BACK&&webView.canGoBack()){
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

代码中详细介绍了 如何 给js传递数据,如何通过js调用Android的方法。

js调用 Android的方法

首先我们需要编写 html代码

代码语言:javascript复制
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<button type="button" id="btn" onclick="pp.show()">html点击</button>
<script>
    function getData(str){
    alert("传递过来的信息是:" str);
    }
</script>
</body>
</html>
代码语言:javascript复制
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<button type="button" id="btn" onclick="pp.show()">html点击</button>

</body>
</html>

我们创建了一个 button 并添加了点击事件 这个点击事件里 有这么一段 pp.show() 这是什么意思呢 ,不要着急,开我们代码

代码语言:javascript复制
 class  jsin{
        Context context;

        public jsin(Context context) {
            this.context = context;
        }
        @JavascriptInterface
        public  void  show(){
            Toast.makeText(context, "这是html点击的", Toast.LENGTH_SHORT).show();
        }
    }

这是我们刚才 MainActivity中的一段代码 ,一个内部类,我们主要看 show()这个方法 ,它使用了 @JavascriptInterface

来标注,这个注解 可以使Android中的方法暴露给 JS,这样我们就可以直接在JS中调用 show()这个方法了,

写好了这个 我们就可以 调用了

webView.addJavascriptInterface(new jsin(getApplicationContext()),"pp"); 注意这里有个 pp,这是我随意定义的,这就是个名字只要保证 与js中相同就行 ,好了到这里应该明白了 pp.show() 的意思了吧。

Android给 JS传值

很简单 就是 webView.loadUrl("javascript:getData('我是Android端的信息')");这一行代码就行了,这行代码给js中的getData()方法传递数据。

代码语言:javascript复制
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<button type="button" id="btn" onclick="pp.show()">html点击</button>
<script>
    function getData(str){
    alert("传递过来的信息是:" str);
    }
</script>
</body>
</html>

好了,到此 我们就把Android与JS的交互学完了。

运行

点击 传递数据到js中

点击 html点击

加油!努力,学习中。

0 人点赞