如何基于使用现状改造:
1 日志和线上监测:
fiddler抓包,chrome Devtools, stecho inspect 注意:chrome Devtools会影响/接管webview本身缓存
线上监测指标:
- 首屏时间: 从外层activity oncreate到webview onFinish回调
- webview内页面切换时间: onstart到onfinish
- dns解析异常,网络连接失败,404,50x的上报和统计
- 缓存目录大小和命中率
2 配备常用的调用android原生的功能
- 拍照/选图->裁剪->压缩--->上传(结合具体项目),返回本地文件路径或者上传好的图片url
- app里已经模块化的自定义拍照功能/人脸检测功能
- 定位功能模块,涵盖获取gps,geodecode,乃至转成自己后台的cityId之类的
- 获取deviceId,uid,userdetail,token,国家,语言等基础业务功能
- 打开,关闭整个activity
- 跳到app内其他页面(通用跳转能力).
- 跳到其他app
- 登录
- 分享
- 拨打电话,以及调用系统其他功能等
- 日志上报功能
- 操控toolbar/titlebar和状态栏,全屏等
需要处理的
- 进度条
- 错误页面: 收到404,50x,以及网络连接失败时加载本地html,以优化体验
- https
- cookie同步
- js调native后与activity的通知: 需要将其移到单独一个类中统一管理
- webview内存泄漏问题
加载速度优化
- 离线包
- 底层灰度+平滑地切换到VasSonic
- 缓存路径自定义和大小自定义
- 强制缓存
安全
- debugable:根据app的debugable来设定
- js注入攻击防范:3个接口的移除
对于Android调用JS代码的方法有2种,综合使用:
- 1.通过WebView的loadUrl()
- 2.通过WebView的evaluateJavascript()
public static void runJsFunc(WebView webView,String funcName,@Nullable ValueCallback<String> callback, Object... params){
if(TextUtils.isEmpty(funcName)){
return;
}
if(webView == null){
return;
}
StringBuilder builder = new StringBuilder(funcName);
builder.append("(");
if(params != null && params.length >0){
int len = params.length;
for (int i = 0; i<len; i++){
Object param = params[i];
String str = "";
if(param != null){
if(param instanceof String){
str = "\""+param.toString()+"\"";
}else {
str = param.toString();
}
}
builder.append(str);
if(i != len-1){
builder.append(",");
}
}
}
builder.append(")");
String jsFunc = builder.toString();
XLogUtil.d("jsFunc:"+jsFunc);
webView.post(() -> {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
//4.4版本以上,调用带返回值js方法
webView.evaluateJavascript(jsFunc, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
XLogUtil.d("jsFunc :"+jsFunc +",onReceiveValue:"+value);
if(callback != null){
callback.onReceiveValue(value);
}
}
});
}else {
webView.loadUrl("javascript:" + jsFunc);
}
});
}
JS调用Android代码的方法有3种:一般用第一种
- 1.通过WebView的addJavascriptInterface()进行对象映射
- 2.通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
- 3.通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
注意: js调用android时的安全性(addJavascriptInterface):
public static void keepsafe(WebView webView,boolean debugable){
if (Build.VERSION.SDK_INT > 10 &&Build.VERSION.SDK_INT < 17) {
webView.removeJavascriptInterface("searchBoxJavaBridge_");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(debugable);
}
}