Android Webview优化及与Js交互

在做的一个项目里主要是webview加载HTML页面,移动端工作量不多,主要是webview的优化问题,虽说看似很简单,但仍遇到了几个令人头疼的问题。
问题解决及优化之路主要经历了以下几个过程:

1、第一次打开webview耗时过长

刚开始在做webview加载url时,发现首次打开页面所耗时长比之后再打开时多了很多。
这是因为webview从创建到加载url需要时间而且首次加载没有缓存。所以最初解决办法是提前创建一个全局webview,供所有页面使用,我是在application初始化时就创建了webview,也确实解决了第一次打开耗时过长问题。

2、H5页面select选择框无法正常使用

在解决第一个问题把webview放在application中后,又出现了新的问题,H5页面里select组件在Android中不能调起,错误原因是Dialog在show的时候必须要有一个activity作为窗口载体,而我的webview是有application创建,并没有任何activity作为载体,所以我又将webview放回activity中创建,发现select选择框果然工作正常了。

3、Webview资源预加载

为了进一步优化加载H5页面耗时过长,数据流量多的问题,我做了资源预加载拦截配置,即将html页面使用到的一些静态资源提前放在Android本地,编译进apk里,在加载页面时,拦截相关的资源,进行替换,节省加载时间和加载的数据量。

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request){}

其中,可以将js,css,图片等资源放置android新建assets文件夹下,拦截到对应url请求后,
用本地数据返回。

return new WebResourceResponse(mimeType, "utf-8", getAssets().open(resourceName));

4、Android webview 与JS交互

因为项目里HTML页面不仅仅是显示效果,还需要和Android本地有一些互动效果或数据交互。所以又涉及到js与Android交互问题。

一、是js调用Android本地代码:

1)先允许与js交互
webSettings.setJavaScriptEnabled(true);
2)添加交互接口
mWebView.addJavascriptInterface(new AndroidtoJs(), “android”);//用this也可以 存在安全隐患 漏洞
//为了防止WebView调用我们不想被它调用的函数,所以我们需要单独为WebView交互定义一个类,让它只执行这个类里面的函数
3)写js需要调用的android代码

 private class AndroidtoJs {
      @android.webkit.JavascriptInterface
      public void finishActivity() {
         finish();
      }
      @android.webkit.JavascriptInterface
      public String toJs() {
          return "123456";
      }   }

4)js端调用
关闭activity例子
function finishActivity(){
window.android.finishActivity();//此即上面finishActivity()
}

二、还有Android调用js代码:

1)js代码(带参例子)
function putData(key,value){
window.localStorage.setItem(key,value);
}

2)Android端调用
此例子是调用带参的方法
mWebView.evaluateJavascript(“javascript:putData(‘serverUrl’,’http://192.168.1.5:8089/‘)”, new ValueCallback() {
@Override
public void onReceiveValue(String value) {
//此处为 js 返回的结果
toast(value);
}
});

5、js与android互调问题,关于localstorage

Webview有多种缓存机制,其中有种Dom Storage 缓存机制,DOM Storage 分为 sessionStorage & localStorage; 二者使用方法基本相同,区别在于作用范围不同:
a. sessionStorage:具备临时性,即存储与页面相关的数据,它在页面关闭后无法使用
b. localStorage:具备持久性,即保存的数据在页面关闭后也可以使用。
问题:android调js,并传送数据 使用localstorage保存。

我们原来的需求是android将一些数据保存在localstorage中,然后js调用获取localstorage中数据。其中,要使用js方法保存数据,如下。
javascript:putData(‘serverUrl’,’http://192.168.1.5:8089/‘)
遇到的问题及注意事项:
1) webview setting需要设置文件缓存等

webSettings.setDomStorageEnabled(true);
webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
webSettings.setAppCachePath(appCachePath);
webSettings.setAppCacheEnabled(true);
webSettings.setAllowFileAccess(true);

2) 刚开始在js加载之前onPageStarted()中调用,发现返回null,这是因为这个页面js还没加载。
3) 在页面onPageFinished()中调用,发现所有资源已加载完,对该需求此时已没意义
所以,这个方法主动调用js并传入数据让js获取,受到js加载时机等因素问题会比较受限,遂放弃。
后来转念一想,改为js主动调用android代码获取想要的数据,实现很简单而且不用考虑js是否已加载,资源加载顺序等问题,需要时即可从android端获取数据。所以有时不能一味根据别人要求完成功能实现,要理清需求,理顺逻辑,才能避免无谓的歪路。

补充调试过程中遇到的几个相关问题:
1、html页面中alert()在android端显示,需要写上

mWebView.setWebChromeClient(new WebChromeClient(){
   @Override
   public boolean onJsAlert(WebView view, String url,String message, JsResult result) {
      toast("message:"+message + "  JsResult" + result.toString());
      return super.onJsAlert(view, url, message, result);
   }
});

2、关于webview缓存
调试时我改动了H5页面,移动端却没有显示出来改动,是因为我为了加快webview加载速度,在webview设置里,对缓存设置里加载使用缓存,而在调试代码过程中,没有清理缓存,所以无论我怎么修改H5页面,移动端始终没有效果,耗费了不少时间和精力,后来加载新页面,才发现是因为缓存,没有实时替换成修改过的HTML页面,而且即使退出应用或重新部署程序也不会自动清理缓存,只有完全手动卸载再安装,才会替换新修改后的页面。所以要在代码里注意添加清理缓存代码。
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android WebView 是一个能够在 Android 应用程序中嵌入网页的组件,它可以开发出能够与 Web 页面进行交互的应用。其中与 Web 页面进行交互的一种方法是与 JavaScript 进行交互。下面简要解释一下 Android WebViewJS 交互的方式。 1. 加载本地 HTML 文件 在 Android WebView 中加载本地 HTML 文件时,需要使用 loadUrl() 方法加载。HTML 文件中的 JavaScript 可以通过 WebView 提供的 addJavascriptInterface() 方法注册为 Java 中的一个对象,然后在 Java 中调用该对象的方法,即可实现 JS 与 Java 的交互。 2. 加载远程 Web 页面 在 Android WebView 中加载远程 Web 页面时,需要添加 WebViewClient 和 WebChromeClient,分别是用来管理 WebView 的网络请求和处理页面上的 JavaScript 弹窗等请求。 在远程 Web 页面上,JS 代码可以通过 WebView 提供的 addJavascriptInterface() 方法注册为 Java 中的一个对象,然后在 Java 中调用该对象的方法,即可实现 JS 与 Java 的交互。 同时,在 Android 中处理 JS 的事件需要通过 JavaScriptInterface 向 WebView 注册一个映射对象,来实现 JS、Java 相互调用的机制,静态 HTML 文件是通过 WebView 中的 evaluateJavascript() 方法来调用 JS,来实现双向通信和数据交互。 总结来说,Android WebViewJS 交互的方式主要是通过 WebView 提供的 addJavascriptInterface() 方法注册为 Java 中的一个对象,然后在 Java 中调用该对象的方法,来实现 JS 和 Java 的交互。同时,JS 也可以通过 WebView 的 evaluateJavascript() 方法来调用 Java 中的方法,实现双向通信和数据交互

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值