转载地址:http://blog.csdn.net/u014315849/article/details/51385266
本篇文章项目github地址:MVPCommon
本文章原地址:简书博客
1 前言
这篇文章将从webview的基础,介绍到项目中的真实使用。以及怎么样通过注入js脚本的方式来改变网页内容,从而在本地展示新闻体育列表。制作出一个像模像样的app。
严正声明,网页数据来自 虎扑体育,仅作学习用途,请勿在任何商业用途中使用。
2 webview基础
WebView是手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装的一个组件。没有提供地址栏和导航栏,WebView只是单纯的展示一个网页界面。在开发中经常都会用到。
2.1 添加webview到应用中
直接将webview添加到layout文件中
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
使用webview加载url使用loadUrl方法:
- 1
- 2
- 1
- 2
AndroidManifest.xml 中必须添加访问网络权限。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
#####2.2 支持JavaScript
如果访问的页面中有 Javascript,则 WebView 初始化的时候必须设置支持 Javascript。(WebSetting中提供了很多有用的api, 点击链接查看)
- 1
- 2
- 3
- 1
- 2
- 3
通过创建JavaScript的接口可以让JavaScript和安卓客户端进行交互。比如说JavaScript可以调用本地的安卓代码展示一个Dialog而不是使用JavaScript的alter()方法。通过addJavascriptInterface()方法创建接口。
示例:
定义一个“接口”类
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
在addJavascriptInterface方法中创建接口
- 1
- 2
- 1
- 2
在HTML的JavaScript中调用WebView显示toast消息,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意:
1 addJavascriptInterface方法中要绑定的Java对象及方法运行在另外的线程中,而不是运行在构造他的线程中。
2 使用addJavascriptInterface将会使javaScript可以操控安卓本地代码。因此有可能导致安全性问题,请确保所有HTML代码都是你所知道的。
3 如果targetSdkVersion是17或者更高(Android 4.2以上),必须使用 @JavascriptInterface 注解,才能让网页访问到本地代码。
2.3 webview页面处理
当用户点击webview中的网页链接的时候,安卓系统默认会启动一个新的应用专门成立url的跳转。如果希望点击链接继续在当前webview中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 WebView的WebViewClient对象. 并重写shouldOverrideUrlLoading方法。
“`
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient.(new WebViewClient();
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals(“www.example.com”)) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there’s history
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
// If it wasn’t the Back key or there’s no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
public class WebViewFragment extends AbsTitleFragment {
……
R.layout.fragment_web_view;
……
@Override
protected void initViewsAndEvents(View rootView) {
mWebView.setVisibility(View.INVISIBLE);
toggleShowLoading(true, "loading");
setWebViewOption(mWebView);
if (getFragmentUrl() != null) {
mWebView.loadUrl(getFragmentUrl());
}
}
private void setWebViewOption(WebView webview) {
......
//设置是否支持运行JavaScript,仅在需要时打开
webview.getSettings().setJavaScriptEnabled(true);
......
//设置WebViewClient
webview.setWebViewClient(new MyWebViewClient());
webview.setWebChromeClient(new MyWebChromeClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// view.loadUrl(url);
Intent intent = new Intent(mContext, WebViewActivity.class);
intent.putExtra(WebViewActivity.WEB_VIEW_URL, url);
startActivity(intent);
return true;
}
……
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
toggleShowLoading(false, "");
if (view.getVisibility() == View.INVISIBLE) {
view.setVisibility(View.VISIBLE);
}
}
……
}
private class MyWebChromeClient extends WebChromeClient {
......
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress > 25) {
injectJS(view);
}
super.onProgressChanged(view, newProgress);
}
}
private void injectJS(WebView webview) {
webview.loadUrl("javascript:(function() " +
"{ " +
"document.getElementsByClassName('m-top-bar')[0].style.display='none'; " +
"document.getElementsByClassName('m-footer')[0].style.display='none';" +
"document.getElementsByClassName('m-page')[0].style.display='none';" +
"})()");
}
}
“`
可以看到WebView的初始化在setWebViewOption方法中进行。其中需要关注的有下面三行代码
上面在WebSetting方法中WebViewClient的初始化,这里主要是点击新闻进行页面跳转的处理。
webview的返回键必须做处理,如果当前webview支持返回(不是点进来的第一个webview,而是再次跳转的),则返回。如果不支持返回(第一个webview界面),则finish当前的页面。
初始化WebView的时候也进行了WebChromeClient的初始化。其中主要是在当进度超过百分之25的时候注入了一段javaScript代码。通过javascript代码去掉了当前网页的头部和底部。
3.4 为什么这么做?
上面就是通过对网页信息注入js的形式,隐藏了相应的属性。
如图,去掉标题栏,在网页中通过F12打开开发者工具,发现顶部栏的class的名字是m-top-bar,所以通过注入脚本的时候直接调用了这个class并且将display置为none。对这方面不了解的可以学习一下HTML5相关的知识。
至于为什么是在进度条进行25之后进行注入,这里主要是在界面加载完成后再进行注入js就会有一定的卡顿闪屏现象。可以自己实践一下。
本篇文章项目github地址:MVPCommon
4 参考链接
Building Web Apps in WebView(官网)
webview reference(官网)
深入讲解WebView-上
深入讲解WebView-下
本篇文章项目github地址:MVPCommon
本文章原地址:简书博客
1 前言
这篇文章将从webview的基础,介绍到项目中的真实使用。以及怎么样通过注入js脚本的方式来改变网页内容,从而在本地展示新闻体育列表。制作出一个像模像样的app。
严正声明,网页数据来自 虎扑体育,仅作学习用途,请勿在任何商业用途中使用。
2 webview基础
WebView是手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装的一个组件。没有提供地址栏和导航栏,WebView只是单纯的展示一个网页界面。在开发中经常都会用到。
2.1 添加webview到应用中
直接将webview添加到layout文件中
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
使用webview加载url使用loadUrl方法:
- 1
- 2
- 1
- 2
AndroidManifest.xml 中必须添加访问网络权限。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
#####2.2 支持JavaScript
如果访问的页面中有 Javascript,则 WebView 初始化的时候必须设置支持 Javascript。(WebSetting中提供了很多有用的api, 点击链接查看)
- 1
- 2
- 3
- 1
- 2
- 3
通过创建JavaScript的接口可以让JavaScript和安卓客户端进行交互。比如说JavaScript可以调用本地的安卓代码展示一个Dialog而不是使用JavaScript的alter()方法。通过addJavascriptInterface()方法创建接口。
示例:
定义一个“接口”类
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
在addJavascriptInterface方法中创建接口
- 1
- 2
- 1
- 2
在HTML的JavaScript中调用WebView显示toast消息,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意:
1 addJavascriptInterface方法中要绑定的Java对象及方法运行在另外的线程中,而不是运行在构造他的线程中。
2 使用addJavascriptInterface将会使javaScript可以操控安卓本地代码。因此有可能导致安全性问题,请确保所有HTML代码都是你所知道的。
3 如果targetSdkVersion是17或者更高(Android 4.2以上),必须使用 @JavascriptInterface 注解,才能让网页访问到本地代码。
2.3 webview页面处理
当用户点击webview中的网页链接的时候,安卓系统默认会启动一个新的应用专门成立url的跳转。如果希望点击链接继续在当前webview中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 WebView的WebViewClient对象. 并重写shouldOverrideUrlLoading方法。
“`
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient.(new WebViewClient();
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals(“www.example.com”)) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there’s history
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
// If it wasn’t the Back key or there’s no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
public class WebViewFragment extends AbsTitleFragment {
……
R.layout.fragment_web_view;
……
@Override
protected void initViewsAndEvents(View rootView) {
mWebView.setVisibility(View.INVISIBLE);
toggleShowLoading(true, "loading");
setWebViewOption(mWebView);
if (getFragmentUrl() != null) {
mWebView.loadUrl(getFragmentUrl());
}
}
private void setWebViewOption(WebView webview) {
......
//设置是否支持运行JavaScript,仅在需要时打开
webview.getSettings().setJavaScriptEnabled(true);
......
//设置WebViewClient
webview.setWebViewClient(new MyWebViewClient());
webview.setWebChromeClient(new MyWebChromeClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// view.loadUrl(url);
Intent intent = new Intent(mContext, WebViewActivity.class);
intent.putExtra(WebViewActivity.WEB_VIEW_URL, url);
startActivity(intent);
return true;
}
……
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
toggleShowLoading(false, "");
if (view.getVisibility() == View.INVISIBLE) {
view.setVisibility(View.VISIBLE);
}
}
……
}
private class MyWebChromeClient extends WebChromeClient {
......
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress > 25) {
injectJS(view);
}
super.onProgressChanged(view, newProgress);
}
}
private void injectJS(WebView webview) {
webview.loadUrl("javascript:(function() " +
"{ " +
"document.getElementsByClassName('m-top-bar')[0].style.display='none'; " +
"document.getElementsByClassName('m-footer')[0].style.display='none';" +
"document.getElementsByClassName('m-page')[0].style.display='none';" +
"})()");
}
}
“`
可以看到WebView的初始化在setWebViewOption方法中进行。其中需要关注的有下面三行代码
上面在WebSetting方法中WebViewClient的初始化,这里主要是点击新闻进行页面跳转的处理。
webview的返回键必须做处理,如果当前webview支持返回(不是点进来的第一个webview,而是再次跳转的),则返回。如果不支持返回(第一个webview界面),则finish当前的页面。
初始化WebView的时候也进行了WebChromeClient的初始化。其中主要是在当进度超过百分之25的时候注入了一段javaScript代码。通过javascript代码去掉了当前网页的头部和底部。
3.4 为什么这么做?
上面就是通过对网页信息注入js的形式,隐藏了相应的属性。
如图,去掉标题栏,在网页中通过F12打开开发者工具,发现顶部栏的class的名字是m-top-bar,所以通过注入脚本的时候直接调用了这个class并且将display置为none。对这方面不了解的可以学习一下HTML5相关的知识。
至于为什么是在进度条进行25之后进行注入,这里主要是在界面加载完成后再进行注入js就会有一定的卡顿闪屏现象。可以自己实践一下。
本篇文章项目github地址:MVPCommon
4 参考链接
Building Web Apps in WebView(官网)
webview reference(官网)
深入讲解WebView-上
深入讲解WebView-下