使用H5的利弊我相信大家都很了解了,这里是入门级的文章我还是说给新同学听一下:

优点:1.跨平台,android和IOS加载同一个H5文件效果是一样的;2.适合动态业务,不如说像商城类的APP可能常常要做促销活动,不同的活动需要不同的主题,用原生的组件是不好实现的,这时候H5的优势就体现出来了,只需要在后台修改H5文件就可以了。题外话:用原生的能不能实现?答案是能,阿里巴巴团队已经开源了自家的解决方案,这个我想留着以后介绍。

缺点:H5之所以没能完全取代原生方案就在于它的缺点和优点一样突出,加载很慢,性能不佳。

因此,目前的情况是这样的:比较固定的业务要用原生的来做,比如注册登录,用户管理等模块,动态业务就用H5,所以目前很多项目都用这种混合开发模式。这就涉及到android与H5的交互问题,下面开始一步步的实现。

一、首先我们来写一个简单的H5测试文件AndroidTest.html文件,我用webStorm来写的,代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>安卓和JS的交互</title>
</head>
<body>
<input type="button" value="打印Log" onclick="javaObject.printLog('test')"/>
<input type="button" value="显示Toast" onclick="javaObject.showToast('test')"/>
<script>
    function toast() {
        alert("test")
    }
</script>
</body>
</html>

关键代码

<input type="button" value="打印Log" οnclick="javaObject.printLog('test')"/>
 <input type="button" value="显示Toast" οnclick="javaObject.showToast('test')"/>
 <script>
     function toast() {
         alert("test")
     }
 </script>

前两行用两个按钮来调用android传过来的javaObject的printLog和showToast方法分别打印日志和吐司。

接下来的一段用JS提供一个方法给android调用,弹出一个提示框。

二、为了方便测试,我们将H5放到本地加载

1.切换到project视图在APP文件夹上右键选择new-Folder-AssetsFolder新建一个assets文件夹,把写好的H5文件放进去待用。

android 调起微信h5 android webview h5_android 调起微信h5

3.我们一般用webView来加载H5文件,所以把webView放到布局文件中,我的布局文件如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <WebView
        android:id="@+id/web"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <Button
        android:id="@+id/test"
        android:layout_centerInParent="true"
        android:text="TEST"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

一个web view用来加载H5,一个按钮用来点击调用JS。

在activity中的代码如下

package com.lsb.www.learnTest;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.ConsoleMessage;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final WebView webview = findViewById(R.id.web);
        WebSettings settings = webview.getSettings();
        settings.setJavaScriptEnabled(true);
        webview.addJavascriptInterface(new JavaObject(this),"javaObject");
        webview.loadUrl("file:///android_asset/AndroidTest.html");
        Button test = findViewById(R.id.test);
        webview.setWebChromeClient(new MyWebChromeClient()); //optional, for show console and alert
        test.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:toast()");
            }
        });


    }

   
    private static class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onConsoleMessage(ConsoleMessage cm) {
            Log.d("test", cm.message() + " -- From line "
                    + cm.lineNumber() + " of "
                    + cm.sourceId() );
            return true;
        }
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//            Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
            return false;
        }
    }

}

需要注意的几点:1. settings.setJavaScriptEnabled(true);这句必须有才能去调用JS;2. webview.addJavascriptInterface(new JavaObject(this),"javaObject");这里给H5传过去一个JavaObject对象给JS调用。3. webview.setWebChromeClient(new MyWebChromeClient());这个必须实现才能正常调起H5里面的弹框!JavaObject的实现如下

package com.lsb.www.learnTest;

import android.content.Context;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

/**
 * Created by Sampson on 2020/5/7.
 * LearnTest
 */
class JavaObject {
    private Context context;

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

    @JavascriptInterface
    public void showToast(String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }

    @JavascriptInterface
    public void printLog(String msg) {
        Log.e("JSTest", msg);
    }
}