WebView交互架构项目实战(一):使用与原理(2)

setContentView(R.layout.activity_main);

WebView webView = (WebView) findViewById(R.id.webview);

webView.getSettings().setJavaScriptEnabled(true);

webView.setWebViewClient(new WebViewClient() {

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

view.loadUrl(url);

return true;

}

@TargetApi(21)

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

view.loadUrl(request.getUrl().toString());

return true;

}

});

webView.loadUrl(“https://ke.youdao.com”);

}

  • 如果访问的页面中含有 JavaScript 的代码,则需要设置 WebView 支持 Javascript。

webView.getSettings().setJavaScriptEnabled(true);

  • 如果页面中含有连接,点击链接如果想继续在当前浏览器中浏览网页,则需要重写 WebView 的 WebViewClient 对象。

webView.setWebViewClient(new WebViewClient() {

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

view.loadUrl(url);

return true;

}

@TargetApi(21)

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

view.loadUrl(request.getUrl().toString());

return true;

}

});

如果不重写 WebView 的对象 WebViewClient,点击页面中的连接则会在手机系统自带的浏览器中打开新的链接。

2. WebViewClient


在第一节中已经简单使用过 WebViewClient 这个类,还有其他一些常用的方法可以重写并使用,其含义如下所示:

webView.setWebViewClient(new WebViewClient() {

// 给应用接管处理某些 url 请求的机会,返回 true 则拦截该请求,返回 false 不拦截,已经被废弃

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

view.loadUrl(url);

return true;

}

// 给应用接管处理某些 url 请求的机会,返回 true 则拦截该请求,返回 false 不拦截,是上面方法的替代方法

// WebResourceRequest 中含有请求的 url,请求方法和请求头等信息

@TargetApi(21)

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

view.loadUrl(request.getUrl().toString());

return true;

}

// 页面开始加载时回调

@Override

public void onPageStarted(WebView view, String url, Bitmap favicon) {

super.onPageStarted(view, url, favicon);

}

// 页面结束加载时回调

@Override

public void onPageFinished(WebView view, String url) {

super.onPageFinished(view, url);

}

// 在加载 url 对应的资源时会回调此方法

@Override

public void onLoadResource(WebView view, String url) {

super.onLoadResource(view, url);

}

// 在加载 url 对应资源时会回调此方法,不同的是,可以通过返回值控制加载的数据。此方法已被废弃

// 若返回 null,WebView 会正常加载该资源

// 若返回 WebResourceResponse 类型的对象,则 WebView 会使用该对象

// 需要注意的是,此方法不在 UI 线程中被调用

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

return super.shouldInterceptRequest(view, url);

}

// 是上面方法的替代方法,使用方法和上面方法一致

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

return super.shouldInterceptRequest(view, request);

}

// 加载资源出错时会被回调的方法

@Override

public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {

super.onReceivedError(view, request, error);

}

// 加载资源时 HTTP 请求出错会回调此方法

@Override

public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {

super.onReceivedHttpError(view, request, errorResponse);

}

// 请求 HTTPS 资源出错时会回调此方法

@Override

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

super.onReceivedSslError(view, handler, error);

}

// 拦截浏览器中的按键事件

// 若返回 true,则拦截按键事件

// 若返回 false,则由 WebView 处理该事件

@Override

public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {

return super.shouldOverrideKeyEvent(view, event);

}

// 当页面的缩放比例发生变化时会回调此方法

@Override

public void onScaleChanged(WebView view, float oldScale, float newScale) {

super.onScaleChanged(view, oldScale, newScale);

}

});

3. WebChromeClient


同 WebViewClient 一样,通过为 WebView 设置 WebChromeClient 对象,并重写其中的一些方法可以对 WebView 的一些行为进行控制。

webView.setWebChromeClient(new WebChromeClient() {

// 网页的加载进度

@Override

public void onProgressChanged(WebView view, int newProgress) {

L.i("onProgressChanged " + newProgress);

super.onProgressChanged(view, newProgress);

}

// 接收到网页的 title

@Override

public void onReceivedTitle(WebView view, String title) {

L.i("onReceivedTitle " + title);

super.onReceivedTitle(view, title);

}

// 接收到网页的 icon

@Override

public void onReceivedIcon(WebView view, Bitmap icon) {

super.onReceivedIcon(view, icon);

}

@Override

public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) {

super.onReceivedTouchIconUrl(view, url, precomposed);

}

// 当 H5 页面中点击播放的 flash video 的全屏按钮时,会调用这个方法

@Override

public void onShowCustomView(View view, CustomViewCallback callback) {

super.onShowCustomView(view, callback);

}

// 与 onShowCustomView() 对应的取消全屏时会调用的方法

@Override

public void onHideCustomView() {

super.onHideCustomView();

}

@Override

public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {

super.onShowCustomView(view, requestedOrientation, callback);

}

// http://www.cnblogs.com/ufreedom/p/4229590.html

// 当创建新的 Window 时会调用此方法

@Override

public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {

return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);

}

// 和 onCreateWindow() 方法对应的,关闭 Window

@Override

public void onCloseWindow(WebView window) {

super.onCloseWindow(window);

}

// 当 WebView 获取焦点时会调用此方法

@Override

public void onRequestFocus(WebView view) {

super.onRequestFocus(view);

}

// 在 Js 代码中弹出 Alert 窗口时会调用此方法

@Override

public boolean onJsAlert(WebView view, String url, String message, JsResult result) {

return super.onJsAlert(view, url, message, result);

}

// 在 Js 代码中弹出 Confirm 窗口时会调用此方法

@Override

public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {

return super.onJsConfirm(view, url, message, result);

}

// 在 Js 代码中弹出 Prompt 窗口时会调用此方法

@Override

public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

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

}

// 在 Js 加载之前会调用此方法

@Override

public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {

return super.onJsBeforeUnload(view, url, message, result);

}

// 打印 Js 中的日志 console 信息,被废弃

@Override

public void onConsoleMessage(String message, int lineNumber, String sourceID) {

super.onConsoleMessage(message, lineNumber, sourceID);

}

// 打印 Js 中的日志 console 信息,被废弃

@Override

public boolean onConsoleMessage(ConsoleMessage consoleMessage) {

return super.onConsoleMessage(consoleMessage);

}

});

4. WebViewClient 和 WebChromeClient 的区别


WebViewClient 主要帮助 WebView 处理一些网络请求方面的行为和操作,比如:各种资源的请求、请求资源出现错误、HTTPS请求出现错误的通知等。

WebChromeClient 主要帮助 WebView 处理一些 Javascript 相关的一些细节,比如:各种对话框的弹出、Js 中日志信息的打印、Window 的创建和关闭、以及 title 和 icon 的接收等。

5. Js 和 Java 代码的交互


Java 代码和 Js 代码额相互调用已经老生常谈了,现在也有一些很优秀的开源框架,使用起来非常的方便,但是其原理都是一样的,下面就介绍一下 Js 代码和 Java 代码是如何进行交互的。

5.1 Js 代码调用 Java 代码

private class InnerClass {

private Context mContext = null;

public InnerClass(Context context) {

mContext = context;

}

@JavascriptInterface

public void toastMessage(String msg) {

Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();

}

}

public class JSBridgeActivity extends AppCompatActivity {

private WebView webView = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_jsbridge);

initWebView();

}

private void initWebView() {

webView = (WebView) findViewById(R.id.webView);

webView.getSettings().setJavaScriptEnabled(true);

webView.addJavascriptInterface(new InnerClass(JSBridgeActivity.this), “innerClass”);

webView.loadUrl(“file:///android_asset/demo.html”);

webView.setWebChromeClient(new WebChromeClient());

}

}

  • 有名为 InnerClass 的类,其中的方法 toastMessage(String msg)@JavascriptInterface 注解所修饰

  • 设置 WebView 对象支持 JavaScript,并且调用 addJavascriptInterface(Object object, String name) 方法,将 InnerClass 的对象传入 WebView 对象中

  • 在 WebView 加载页面的 Js 代码中,即可通过 name 调用 InnerClass 对象的 toastMessage(String msg) 方法,如下所示:

function testPrompt(){

window.innerClass.toastMessage(“jsbridge”);

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
(“jsbridge”);

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-sR3k0pSe-1715710299109)]

[外链图片转存中…(img-TgXOpLV6-1715710299109)]

[外链图片转存中…(img-lZGyBMgq-1715710299110)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值