如何设计一个优雅健壮的Android WebView?,吊打面试官系列

     }
    if (mIWebViewClient != null) {
        mIWebViewClient.onPageFinished(view, newProgress);
    }
}

}


可以看到,我们使用了`mProgressFinishThreshold`这个变量控制注入时机,这与前面提及的`当progress达到80的时候,加载出来的页面已经基本可用了`是相呼应的。

> 达到80%很容易,达到100%却很难。

正是因为这个原因,页面的进度加载到80%的时候,实际上dom树已经渲染得差不多了,表明WebView已经解析了<html>标签,这时候注入一定是成功的。在`WebViewClient.onProgressChanged()`实现js注入有几个需要注意的地方:

1.  上文提到的多次注入控制,我们使用了mCallProgressCallback变量控制
2.  重新加载一个URL之前,需要重置mCallProgressCallback,让重新加载后的页面再次注入js
3.  注入的进度阈值可以自由定制,理论上10%-100%都是合理的,我们使用了80%。

H5页面、Weex页面与Native页面交互——KaolaRouter
-----------------------------------

H5页面、Weex页面与Native页面的交互是通过URL拦截实现的。在WebView中,`WebViewClient.shouldOverrideUrlLoading()`方法能够获取到当前加载的URL,然后把URL传递给考拉路由框架,便可以判断URL是否能够跳转到其他非H5页面,考拉路由框架在[《考拉Android客户端路由总线设计》]( )一文中有详细介绍,但当时未引入Weex页面,关于如何整合三者的通信,后续文章会有详细介绍。

在`WebViewClient.shouldOverrideUrlLoading()`中,根据URL类型做了判断:

public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (StringUtils.isNotBlank(url) && url.equals(“about:blank”)) { //js调用reload刷新页面时候,个别机型跳到空页面问题修复
url = getUrl();
}
url = WebViewUtils.removeBlank(url);
mCallProgressCallback = true;
//允许启动第三方应用客户端
if (WebViewUtils.canHandleUrl(url)) {
boolean handleByCaller = false;
// 如果不是用户触发的操作,就没有必要交给上层处理了,直接走url拦截规则。
if (null != mIWebViewClient && isTouchByUser()) {
// 先交给业务层拦截处理
handleByCaller = mIWebViewClient.shouldOverrideUrlLoading(view, url);
}
if (!handleByCaller) {
// 业务层不拦截,走通用路由总线规则
handleByCaller = handleOverrideUrl(url);
}
mRedirectProtected = true;
return handleByCaller || super.shouldOverrideUrlLoading(view, url);
} else {
try {
notifyBeforeLoadUrl(url);
// https://sumile.cn/archives/1223.html
Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(null);
intent.setSelector(null);
mContext.startActivity(intent);
if (!mIsBlankPageRedirect) {
back();
}
} catch (Exception e) {
ExceptionUtils.printExceptionTrace(e);
}
return true;
}
}

private boolean handleOverrideUrl(final String url) {
RouterResult result = WebActivityRouter.startFromWeb(
new IntentBuilder(mContext, url).setRouterActivityResult(new RouterActivityResult() {
@Override
public void onActivityFound() {
if (!mIsBlankPageRedirect) {
// 路由拦截成功以后,为防止首次进入WebView产生白屏,因此加了保护机制
back();
}
}

            @Override
            public void onActivityNotFound() {
                
            }
        }));
return result.isSuccess();

}


代码里写了注释,就不一一解释了。

WebView下拉刷新实现
-------------

由于考拉使用的下拉刷新跟Material Design所使用的下拉刷新样式不一致,因此不能直接套用`SwipeRefreshLayout`。考拉使用的是一套改造过的[Android-PullToRefresh]( ),WebView的下拉刷新,正是继承自`PullToRefreshBase`来实现的。

/**

  • 创建者:Square Xu

  • 日期:2017/2/23

  • 功能模块:webview下拉刷新组件
    */
    public class PullToRefreshWebView extends PullToRefreshBase {
    public PullToRefreshWebView(Context context) {
    super(context);
    }

    public PullToRefreshWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
    }

    public PullToRefreshWebView(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs);
    }

    public PullToRefreshWebView(Context context, Mode mode) {
    super(context, mode);
    }

    public PullToRefreshWebView(Context context, Mode mode, AnimationStyle animStyle) {
    super(context, mode, animStyle);
    }

    @

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值