安卓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进行了全新设计,坚持 ...
随机推荐
- ajax ★ ★ ★ ★ ★
ajax 1 定义: 是创建交互式应用的网页交互技术 2 特点:无刷新.异步 3 中介数据类型: 1) XML - 可扩展的标记语言 ...
- 3. pkg
程序打包成可执行文件(.exe) 1.) npm install -g pkg 2.) 单个文件:pkg entrance.js ( windows: pkg -t win entrance.js ...
- [GO] mac安装GO 初次尝试
其实试了好多方法,我用的是下面这种方法,简单快捷! 安装homebrew 在终端输入命令 ruby -e "$(curl -fsSL https://raw.githubuserconten ...
- 你知道什么是 GitHub Action 么?
本文是 GitHub Action 的入门教程,如您已有相关使用经验可以直接关掉. GitHub Action 是 GitHub 于 2018 年 10 月推出的一个 CI\CD 服务. 之前一直都是 ...
- 关于virtual box 虚拟机使用
关于virtual box的使用,如果想用共享文档:比如当前系统为Ubuntu,virtual box安装了win7,win7与Ubuntu之间的文件使用,就可以利用 共享文档 这个便利的功能—— 在 ...
- Linux中find常见用法示例 ·find path -option [ -print ] [ -exec -ok command ] {} \;
find命令的参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系统根目录.-print: find命令将匹配的文件输出到标准输出.-exec: find命令 ...
- 大数据hbase分布式安装及其部署。
大数据hbase分布式安装及其部署. 首先要启动Hadoop以及zookeeper,可以参考前面发布的文章. 将hbase的包上传至master节点 这里我使用的是1.3.6的版本,具体的根据自己的版 ...
- c语言-----劫持自己02
在上一节 c语言-----劫持原理01 已经叙述了劫持原理,下边正式进入劫持实战 1. 需要实现的功能 在c语言中 system("notepad") 可以打开一个记事本 syst ...
- Python内置函数enumerate()
enumerate()是Python的内置函数. help(enumerate) Help on class enumerate in module builtins: class enumerate ...
- Swift-Realm数据库的使用详解
Swift-Realm数据库的使用详解 概述 Realm 是一个跨平台的移动数据库引擎,其性能要优于 Core Data 和 FMDB - 移动端数据库性能比较, 我们可以在 Android 端 re ...