安卓APP承载网页(WebView)
安卓APP自身如何打开网页,如何制作一个简单的浏览器,WebView在其中将是一个重要的角色。WebView是一个基于WebKit引擎、展现Web页面的控件。
Webview 是一个基于webkit引擎,可以解析DOM 元素,展示html页面的控件,它和浏览器展示页面的原理是相同的,所以可以把它当做浏览器看待。(chrome浏览器也是基于webkit引擎开发的,Mozilla浏览器是基于Gecko引擎开发的)
简而言之,WebView可以实现安卓APP中承载网页
手机浏览器:
国内手机的自带浏览器不是chrome,主要是版权的原因,自带的浏览器都是手机厂商基于国内主流的几大浏览器自己定制,然后发布在自己手机系统版本中.不过国内几大浏览器厂商如QQ浏览器,UC浏览器、都是基于webkit引擎的,iphone的自带浏览器是Safari,Safari浏览器的内核是webkit
使用WebView的好处:
- 使用内核都是webkit,所以APP中网页展示的效果与主流浏览器差别无几
- 这是一个BS架构即浏览器和服务器的,所以在某些要经常改变的界面嵌入WebView,可以方便随时在后台修改其内容
加载一个网页的方法
加载服务器的网页
//获取到webview控件
WebView webv=findViewById(R.id.mywebview);
//加载网页
webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");
加载资源文件(assets目录)的网页
assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件。
//获取到webview控件
WebView webv=findViewById(R.id.mywebview);
//加载网页
webv.loadUrl("file:///android_asset/androidt.html");
网页加载时附加网页代码
baseUrl表示基础的网页
data表示要加载的内容
mimeType表示加载网页的类型
encoding表示编码格式
historyUrl表示可用历史记录,可以为null值
webv.loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl))
网页浏览器的基础属性
canGoBack() 是否可以后退
canGoForward() 是否可以前进
canGoBackOrForward(int step) 是否可以前进或者后退多少步,正数为前进,负数为后退
goBack() 后退
goBack() 前进
goBackOrForward(int step)前进或者后退多少步,正数为前进,负数为后退
reload() 重新加载或刷新界面
stopLoading() 停止加载
实现:
//后退函数实现
public void But_back(View v){
//查询是否可以返回上一级
boolean canx=webv.canGoBack();
//返回上一级
if(canx) webv.goBack();
//不可返回
else Toast.makeText(MainActivity.this,"已经到达底端",Toast.LENGTH_SHORT).show();
}
//前进函数实现
public void But_forward(View v){
boolean canx=webv.canGoForward();
//返回上一级
//查询是否可以返回上一级
if(canx) webv.goForward();
//不可返回
else Toast.makeText(MainActivity.this,"已经到达顶端",Toast.LENGTH_SHORT).show();
}
//刷新页面
public void But_reload(View v){
webv.reload();
}
//停止界面加载
public void But_stop(View v){
webv.stopLoading();
}
WebView配置类(WebSettings)
WebSettings webSettings = webView.getSettings();
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
webSettings.setJavaScriptEnabled(true); //设置自适应屏幕,两者合用
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局 //缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
webSettings.setTextZoom(2);//设置文本的缩放倍数,默认为 100 webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH); //提高渲染的优先级 webSettings.setStandardFontFamily("");//设置 WebView 的字体,默认字体为 "sans-serif"
webSettings.setDefaultFontSize(20);//设置 WebView 字体的大小,默认大小为 16
webSettings.setMinimumFontSize(12);//设置 WebView 支持的最小字体大小,默认为 8 // 5.1以上默认禁止了https和http混用,以下方式是开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
} //其他操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
webSettings.setGeolocationEnabled(true);//允许网页执行定位操作
webSettings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");//设置User-Agent //不允许访问本地文件(不影响assets和resources资源的加载)
webSettings.setAllowFileAccess(false);
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
事件监听
各种通知和请求事件(WebViewClient)
onPageStarted() 页面加载时
onPageFinished():页面加载完毕时调用。
shouldOverrideKeyEvent():重写此方法才能处理浏览器中的按键事件。
shouldInterceptRequest():页面每一次请求资源之前都会调用这个方法(非UI线程调用)。
onLoadResource():页面加载资源时调用,每加载一个资源(比如图片)就调用一次。
onReceivedError():加载页面的服务器出现错误(比如404)时回调。
onReceivedSslError():重写此方法可以让webview处理https请求。
doUpdateVisitedHistory():更新历史记录。
onFormResubmission():应用程序重新请求网页数据。
onReceivedHttpAuthRequest():获取返回信息授权请求。
onScaleChanged():WebView发生缩放改变时调用。
onUnhandledKeyEvent():Key事件未被加载时调用。
辅助 WebView 处理补充问题(WebChromeClient)
onProgressChanged():获得网页的加载进度并显示。
onReceivedTitle():获得网页的标题时回调。
onReceivedIcon():获得网页的图标时回调。
onCreateWindow():打开新窗口时回调。
onCloseWindow():关闭窗口时回调。
onJsAlert():网页弹出提示框时触发此方法。
上例程
统一统一步骤:
第一步:
在AndroidManifest.xml下添加网络访问权限,如果需要外网访问的情况下
<!--网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!--文件读写权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
第二步:
在xml下添加WebView控件
<WebView
android:layout_width="match_parent"
android:id="@+id/mywebview"
android:layout_height="match_parent" />
加载可服务器的网页:
这里将使用WebView打开 博客园 东小东 的博客首页
第三步:
编写逻辑程序
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView webv=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取到webview控件
webv=findViewById(R.id.mywebview);
//设置访问的URL,此条将会触发系统调用浏览器打开,博客园东小东
webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");
//通过下面的代码阻止APP直接通过浏览器打开网页
webv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载URL内容
view.loadUrl(url);
return true;
}
});
}
//监听程序的返回事件
public boolean onKeyDown(int keyCode, KeyEvent event) {
//如果按下返回键且网页有历史记录,可以返回上一级
if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
//返回上一级
webv.goBack();
return true;
}
//否则返回真实的按键信息给系统,系统将将退出程序
return super.onKeyDown(keyCode, event);
}
}
加载资源文件(assets目录)的网页
assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件。
第三步:
编写HTML代码,保存到文件androidt.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>这里是网页头</title>
</head>
<body style="margin: 0 auto;text-align: center">
<h1>我是网页标题1</h1>
<h3>(资源文件方法)</h3>
<button onClick="showA()" style="width: 100%;height: 100px;">点我弹框</button>
</body>
<script>
function showA(){
alert("弹框内容,完成");
}
</script>
</html>
第四步
创建assets目录
右键【app】-【New】-【Folder】-【Assets Folder】-【finish】
第五步
将HTML文件拷贝到assets目录下
第六步
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取到webview控件
WebView webv=findViewById(R.id.mywebview); WebSettings webSettings = webv.getSettings();
webSettings.setJavaScriptEnabled(true);//设置支持Javascript
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);//允许js弹出窗口 //访问本地资源文件网页
webv.loadUrl("file:///android_asset/androidt.html"); //通过下面的代码阻止APP直接通过浏览器打开网页
webv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载URL内容
view.loadUrl(url);
return true;
}
});
//如果要实习alert弹框,必须实现此监听事件
webv.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// TODO Auto-generated method stub
return super.onJsAlert(view, url, message, result);
}
});
}
}
加载部分源代码
直接写一部分的HTML代码,可以直接显示在WebView上
第三步:
编写逻辑程序
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView webv=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取到webview控件
webv=findViewById(R.id.mywebview);
WebSettings webSettings = webv.getSettings(); //将网页界面缩放至手机屏幕大小
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 //设置支持缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件 //编辑网页代码
String myhtml="<h1 >东小东标题</h1>" +
"<hr/>" +
"<a href='https://www.cnblogs.com/dongxiaodong/'>去东小东博客园看看<a/>" +
"<h3 >网页显示小标题</h3>" +
"<img style=\"width: 100%;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";
//设置显示
webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null); //通过下面的代码阻止APP直接通过浏览器打开网页
webv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载URL内容
view.loadUrl(url);
return true;
}
});
}
//监听程序的返回事件
public boolean onKeyDown(int keyCode, KeyEvent event) {
//如果按下返回键且网页有历史记录,可以返回上一级
if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
//返回上一级
webv.goBack();
return true;
}
//否则返回真实的按键信息给系统,系统将将退出程序
return super.onKeyDown(keyCode, event);
}
}
综合案例
缺点:工程未实现网页的音频和视频播放
实现功能:
l 标题显示
l 网页加载进度条显示
l 后退、前进、刷新、停止加载四大常用功能适配
l 连接跳转,在APP本地打开网页
视图源码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15dp"
android:id="@+id/show_text"
android:background="@color/colorPrimary"
android:text="标题显示"/>
<ProgressBar
android:max="100"
android:progress="10"
android:id="@+id/show_progres"
style="?android:attr/progressBarStyleHorizontal"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"/> <WebView
android:layout_width="match_parent"
android:id="@+id/mywebview"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal"> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="But_back"
android:text="后退"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="But_forward"
android:layout_weight="1"
android:text="前进"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="But_reload"
android:layout_weight="1"
android:text="刷新"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="But_stop"
android:layout_weight="1"
android:text="停止"/> </LinearLayout> </FrameLayout>
逻辑源码
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends AppCompatActivity {
private WebView webv=null;
private TextView showtext=null;
private ProgressBar showpro=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏状态栏
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
//获取到webview控件
webv=findViewById(R.id.mywebview);
showtext=findViewById(R.id.show_text);
showpro=findViewById(R.id.show_progres); WebSettings webSettings = webv.getSettings(); webSettings .setAllowFileAccess(true);
//设置支持缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件 //编辑网页代码
String myhtml="<h1 >东小东标题</h1>" +
"<hr/>" +
"<h2><a href='https://www.cnblogs.com/dongxiaodong/'>去东小东博客园看看<a/></h2>" +
"<h3 >网页显示小标题</h3>" +
"<img style=\"width: 300px;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";
//设置显示
webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null); //通过下面的代码阻止APP直接通过浏览器打开网页
webv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载URL内容
view.loadUrl(url);
return true;
}
});
webv.setWebChromeClient(new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
//标题显示
showtext.setText(title);
//Toast.makeText(MainActivity.this,title,Toast.LENGTH_SHORT).show();
} @Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//进度条显示
showpro.setProgress(newProgress);
//Toast.makeText(MainActivity.this,newProgress+"",Toast.LENGTH_SHORT).show();
}
}); }
//监听程序的返回事件
public boolean onKeyDown(int keyCode, KeyEvent event) {
//如果按下返回键且网页有历史记录,可以返回上一级
if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
//返回上一级
webv.goBack();
return true;
}
//否则返回真实的按键信息给系统,系统将将退出程序
return super.onKeyDown(keyCode, event);
} //后退函数实现
public void But_back(View v){
//查询是否可以返回上一级
boolean canx=webv.canGoBack();
//返回上一级
if(canx) webv.goBack();
//不可返回
else Toast.makeText(MainActivity.this,"已经到达底端",Toast.LENGTH_SHORT).show();
}
//前进函数实现
public void But_forward(View v){
boolean canx=webv.canGoForward();
//返回上一级
//查询是否可以返回上一级
if(canx) webv.goForward();
//不可返回
else Toast.makeText(MainActivity.this,"已经到达顶端",Toast.LENGTH_SHORT).show();
}
//刷新页面
public void But_reload(View v){
webv.reload();
}
//停止界面加载
public void But_stop(View v){
webv.stopLoading();
}
}
参考:
https://blog.csdn.net/Jolting/article/details/81223904?utm_source=blogxgwz9
https://blog.csdn.net/weixin_40438421/article/details/85700109
https://www.jianshu.com/p/3e0136c9e748
安卓APP承载网页(WebView)的更多相关文章
- 【安卓小技巧】WebView设置在本页面打开网页,而不是启动浏览器打开
使用WebView可以巧妙的在安卓APP中嵌入HTML页面, WebView wb = (WebView) findViewById(R.id.web); //找到WebView控件 wb.setWe ...
- H5网页应用打包安卓App (全网最详细教程)
img { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important } .red { color: rgba(255, 0, 0, 1) } ...
- 安卓APP载入HTML5页面解决方式总结
因为H5页面在移动端的兼容性及扩展性方面体现出来的优势,又兼得APP中植入H5页面相应用的灵活性有大大的提升(如活动.游戏的更新等).APP开发不可避免的须要载入一些H5页面.但安卓client对网页 ...
- 安卓开发_关于WebView加载页面空白问题
依据我自己的测试,发现有时候用APP打开网页的时候,有的网页加载成功之前需要很久,有的一下就出来了(比如百度) 当加载时间过长的情况下,这时候显示的是空白界面,其实不是代码问题,只是要打开的这个网页太 ...
- webapp检测安卓app是否安装并launch
1. cordova插件 1)查看所有已安装的安卓app https://www.npmjs.com/package/cordova-plugin-packagemanager A simple pl ...
- 关于安卓APP的启动界面
刚学安卓App开发的朋友们,可能会遇到一个问题,就是人家的App刚进入会有一个页面出现一会儿后消失, 这个页面可以用来打广告,也可以声明App的主题,所以说这个启动页面至关重要,接下来,我把我的代 ...
- 安卓APP测试验证点总结
最近较懒,加之闺女出生后记忆没完全恢复,总是忘东忘西,关于安卓APP测试的验证点还是总结一下,方便设计测试用例时查阅,也给各位博友参考! 1.除APP的正常功能点外,还有以下验证点: 安装/卸载(考虑 ...
- 【转载】安卓APP架构
注:本篇博文转载于 http://my.oschina.net/mengshuai/blog/541314?fromerr=z8tDxWUH 本文介绍了文章作者从事了几年android应用的开发,经历 ...
- 安卓app设计规范整理和Android APP设计篇(转)
随着安卓智能手机不停的更新换代.安卓手机系统越来越完美,屏幕尺寸也越来越大啦!比如最近小米的miui 6的发布和魅族手机系统的更新等等. 以小米MIUI6的安卓手机来说,MIUI6进行了全新设计,坚持 ...
随机推荐
- MySQL的单表查询
单表查询 单表查询语法: select distinct 字段1,字段2... from 表名 where 条件 group by field having筛选 order by 关键字执行的优先级: ...
- 跨行程序员Java进阶--基础语法
1.基础语法 Hello Wolrd 首先定义类 -- public class 类名 在类定义之后加上一对大括号 -- {} 在大括号中间添加一个主(main)方法/函数 -- public sta ...
- Linux服务器压力测试总结(CPU、Memory、IO等)
测试工具:sysbench.memtester.htop 1.htop安装使用 yum install ncurses-devel # 安装依赖包 tar zxvf htop-2.2.0.tar.gz ...
- TortoiseSVN的使用,以及冲突解决办法
接下来,试试用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突等. 添加文件 在检出的工作副本中添加一个Readme.txt文本文件,这时候这个文本文件会显示为没有版本控制的状态, ...
- selemiun 问题总结
1.如果打开一个网页定位一个元素时发现不能够定位某一个元素,并且定位的方法没问题,则需要看下该网页是否有frame框架 解决办法: 如果有frame框架则需要先切换到frame框架下: driver. ...
- XSS语义分析的阶段性总结(一)
本文作者:Kale 前言 由于X3Scan的研发已经有些进展了,所以对这一阶段的工作做一下总结!对于X3Scan的定位,我更加倾向于主动+被动的结合.主动的方面主要体现在可以主动抓取页面链接并发起请求 ...
- 模拟HTTP请求调用controller
原文参考本人的简书:https://www.jianshu.com/p/0221edbe1598 MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller调用,这样 ...
- ip的运用
1------获取ip$ip=$_SERVICE['REMOTE_ADDR'];2------根据ip获取主机名gethostbyaddr($ip);3------根据主机名获取IPgethostby ...
- [Batch脚本] if else 的格式
必须写成一行 ) else (,否则报错. if %abc%=="yes" ( ... ) else ( ... )
- Codeforces Round #628 (Div. 2) 题解
人闲桂花落,夜静春山空. 月出惊山鸟,时鸣春涧中.--王维 A. EhAb AnD gCd You are given a positive integer x. Find any such 2 po ...