WebView与Android原生通信

1.Android中打开本地的HTML

Android中打开本地的HTML
初始化WebView,加载本地的Html文件

javaMethod = new JavaMethod(this);
        webView = new WebView(this);
        WebSettings settings = webView.getSettings();
        settings.setDomStorageEnabled(true);
        settings.setJavaScriptEnabled(true);
        settings.setBlockNetworkImage(false);
        webView.setWebViewClient(javaMethod.getWebViewClient());
        webView.setWebChromeClient(javaMethod.getWebChromeClient());
        webView.addJavascriptInterface(javaMethod, "android");
        frameLayout.addView(webView);

        // webView加载一个网页
        webView.loadUrl("file:///android_asset/test_js.html");

js调用native

1. 借助WebView.addJavascriptInterface实现H5与Native通信

WebView的addJavascriptInterface方法允许Natvive向Web页面注入Java对象,之后,在js中便可以直接访问该对象,使用@JavascriptInterface注解的方法。

public class JavaMethod {
    private MainActivity mainActivity;
    private Handler uiHandler;

    public JavaMethod(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
        uiHandler = new Handler(Looper.getMainLooper());
    }

    @JavascriptInterface
    public void JsToJavaInterface(final String param) {
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                mainActivity.setTextShow("from JavaInterface: " + param);
            }
        });
    }
}

在前端的js代码中,是可以直接通过mJsMethodApi.callNative(jsonString)通知Native的,而且通过addJavascriptInterface注入的对象在H5的任何地方都可以调用,不存在注入时机跟注入失败的问题,在H5的head里调用都没问题

<html>

    <head>
        <meta http-equiv="Content-Type" charset="UTF-8"/>

        <script type="text/javascript">
        </script>
    </head>

    <body>

        <h3>Js Method</h3>
        <h3 id="textshow">调用结果</h3>
        
        <input type="button" value="JavascriptInterface" onclick="window.android.JsToJavaInterface('我来自Js')"/>

    </body>

</html>

2. shouldOverrideUrlLoading

通过WebViewClient中的shouldOverrideUrlLoading拦截url,制定一个对应协议。
在Html中增加一条

<input type="button" value="shouldOverrideUrlLoading" onclick="document.location = 'js://jstojava?arg1=1号参数&arg2=2号参数'"/>

在Android代码中拦截url

 /**
     * shouldOverrideUrlLoading:webViewClient加载url时候的回调
     *
     * @return WebViewClient
     */
    public WebViewClient getWebViewClient() {
        WebViewClient webViewClient = new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                Uri uri = request.getUrl();
                // 与JS端定义好协议:  一般协议格式是Scheme(协议头)+ Authority(协议名)
                if (uri != null) {
                    String scheme = uri.getScheme();
                    if (scheme != null && scheme.equals("js")) {
                        String authority = uri.getAuthority();
                        if (authority != null && authority.equals("jstojava")) {
                            // 获取参数
                            String arg1 = uri.getQueryParameter("arg1");
                            String arg2 = uri.getQueryParameter("arg2");

                            showText(MessageFormat.format("参数: {0}; {1}", arg1, arg2));
                            Log.e("==TAG==>", "参数 -> arg1:" + arg1 + " ; arg2:" + arg2);

                        }
                        return true;
                    }
                }
                return super.shouldOverrideUrlLoading(view, request);
            }
        };
        return webViewClient;
    }

这种方式没有版本限制和漏洞,不过没有返回值,如果Js调用后需要android返回就得使用loadUrl()或者evaluateJavascript()回传对应的接收方法了。值得一提的是,这种方式便于和IOS通用一套协议,简便Js端的代码量。

3. onJsAlert()、onJsConfirm()、onJsPrompt()

通过 WebChromeClient 中的onJsAlert()、onJsConfirm()、onJsPrompt()拦截Js中的alert()、confirm()、prompt() 消息。而alert、confirm、prompt代表Js中三种常用提示框,第一种没有返回值,第二种返回布尔值,第三种可返回任意值。由于考虑到灵活性,所以我们可以直接实现对prompt的拦截即可。

在Html中添加

  <script type="text/javascript">
        function jstojavaprompt(param){
             result = prompt(param);
             document.getElementById("textshow").innerHTML = (result);
        }
    </script>
...
<input type="button" value="onJsPrompt"
       onclick="jstojavaprompt('js://jstojava?arg3=1号参数&arg4=2号参数')"/><br/>

代码中设置setWebChromClient(),拦截onJsPrompt

    /**
     * onJsPrompt:调用本地方法jstojavaprompt(),然后回调onJsPrompt()
     *
     * @return WebChromeClient
     */
    public WebChromeClient getWebChromeClient() {
        return new WebChromeClient() {
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                Log.e("==TAG==>", "url:" + url);
                Uri uri = Uri.parse(message);
                // 与JS端定义好协议:  一般协议格式是Scheme(协议头)+ Authority(协议名)
                if (uri != null) {
                    String scheme = uri.getScheme();
                    if (scheme != null && scheme.equals("js")) {
                        String authority = uri.getAuthority();
                        if (authority != null && authority.equals("jstojava")) {
                            // 获取参数
                            String arg1 = uri.getQueryParameter("arg3");
                            String arg2 = uri.getQueryParameter("arg4");

                            showText(MessageFormat.format("参数: {0}; {1}", arg1, arg2));
                            Log.e("==TAG==>", "参数 -> arg1:" + arg1 + " ; arg2:" + arg2);

                            result.confirm("我来自onJsPrompt");

                        }
                        return true;
                    }
                }
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
        };

    }

Native调用JS

1. loadUrl() 方式

在Html中添加JS方法

<script type="text/javascript">
var s = '我来自Js方法';
        function javatojscallback(param){
             document.getElementById("textshow").innerHTML = (param);
             window.android.jsCallbackParams(s)
        }
</script>

window.android.JsToJavaInterface(s)是Js调用android的方法,由于loadUrl()不能从Js返回数据,可以让Js回调android的方法回传参数。

在Android代码中添加接收Js回调传参的方法

  // Js回调Android的方法,传递参数
    @JavascriptInterface
    public void jsCallbackParams(String params){
        showText(params);
    }

在Android中调用JS方法

/**
     * 通过 webView.loadUrl 调用JS
     *
     * @param view view
     */
    public void loadUrl(View view) {
        webView.loadUrl("javascript:javatojscallback('我来自Java')");
    }

2. evaluateJavascript()方式

在Html中定义js的方法,供Java调用

var s = '我来自Js方法';
function javatojswith(param){
             document.getElementById("textshow").innerHTML = (param);
             return s;
        }

在Android中通过webView.evaluateJavascript()调用JS中的方法

/**
     * 通过 webView.evaluateJavascript 调用JS
     *
     * @param view
     */
    public void evaluate(View view) {
        webView.evaluateJavascript("javascript:javatojswith('这是来自Java的参数')",
                new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        setTextShow(value);
                        Toast.makeText(WebActivity.this, value, Toast.LENGTH_SHORT).show();
                    }
                });
    }

WebView优化

为什么拥有Webview的H5页面打开这么慢,是因为它通常会经历以下几个阶段:
1)Webview初始化。
2)到达新的页面,网络连接,从服务器下载html,css,js,页面白屏。
3)页面基本框架出现,js请求页面数据,页面处于loading状态。
4)出现所需的数据,完成整个页面的渲染,用户可交互。

  1. Webview提前初始化
    提前加载WebView,进行WebView的初始化。加载Webview内核,这是一个重量级的操作,内核是以apk的形式存在。
    App生成一个全局webview,并且在启动时初始化,这样在后面使用时通过动态获取这个全局Webview,然后添加到rootview中,这样就可以进行复用从而减少初始化的时间。

注意:如果在不同页面使用Webview时使用不同的设置,就需要动态维护,而且在不同的页面跳转前要做好清理工作。

  1. H5页面拉取优化
    可以把html,css,js,image等资源预置在客户端本地,并和服务端协商好前端的版本控制和增量更新策略,如此一来Webview就可以先快速加载本地缓存页面资源,剩下的就只需要拉取那些需要更新的增量资源即可。

而针对这些需要拉取的增量资源,可以对它们进行webpack+gzip数据压缩和CDN加速处理,以提升拉取速度。并且在建立网络连接时,可以让前端请求的域名和客户端API接口域名一致,以减少DNS解析时间。

对于H5页面来说,图片资源的拉取是最为耗时的,一个比较好的解决方案就是先加载并展示非图片内容,延迟这些图片的加载,以提升用户体验。

WebView有一个setBlockNetworkImage(boolean)方法,该方法的作用是是否屏蔽图片的加载。可以利用这个方法来实现图片的延迟加载:在onPageStarted时屏蔽图片加载,在onPageFinished时开启图片加载。

  1. H5动态数据拉取并行
    正常的顺序是在html,css,js拉取下来之后,才开始由js发起前端的ajax请求,获取到数据后才开始进行填充。

其实我们可以把前端的ajax请求提前到和页面加载同时进行,由客户端请求数据,等到H5加载完毕,直接向客户端索要即可,缩短了总体的页面加载时间。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android Studio中与Vue项目交互,您可以使用WebView来加载Vue项目,并通过WebViewAndroid原生代码进行交互。 以下是一些步骤: 1. 在Android Studio中创建一个新的Android项目。 2. 在app/build.gradle文件中,添加WebView的依赖: ```groovy implementation 'androidx.webkit:webkit:1.4.0' ``` 3. 在您的布局文件中,添加一个WebView: ```xml <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 4. 在您的Activity中,初始化WebView并加载Vue项目: ```java WebView webView = findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/vue_project/index.html"); ``` 这里的"vue_project"是您Vue项目的文件夹名字,确保它在Android项目的assets目录下。 5. 在Vue项目中,您可以使用Vue的内置方法通过WebViewAndroid原生代码进行通信。例如,您可以使用JavaScript与Java代码交互: ```javascript // 在Vue中调用Android方法 window.AndroidInterface.showToast('Hello from Vue'); // 在Java中定义供Vue调用的方法 public class AndroidInterface { @JavascriptInterface public void showToast(String message) { Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); } } ``` 请注意,要使此方法生效,您需要为WebView启用JavaScript,并将AndroidInterface类添加为JavaScript接口: ```java webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new AndroidInterface(), "AndroidInterface"); ``` 这样,您就可以在Android Studio中加载Vue项目,并使用WebView进行Android与Vue项目的交互了。请注意,这只是其中一种实现方式,您可以根据您的需求和项目结构进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值