当前位置: 移动技术网 > 移动技术>移动开发>Android > android WebView加载html5介绍

android WebView加载html5介绍

2019年07月24日  | 移动技术网移动技术  | 我要评论
android设备多分辨率的问题
android浏览器默认预览模式浏览 会缩小页面 webview中则会以原始大小显示
android浏览器和webview默认为mdpi。hdpi相当于mdpi的1.5倍 ldpi相当于0.75倍
三种解决方式:1 viewport属性 2 css控制 3 js控制
1 viewport属性放在html的<meta>中
html代码
复制代码 代码如下:

<spanstyle="font-size: x-small"> <head>
<title>exmaple</title>
<metaname=”viewport” content=”width=device-width,user-scalable=no”/>
</head></span>

meta中viewport的属性如下
html代码
复制代码 代码如下:

<spanstyle="font-size: x-small"> <metaname="viewport"
content="
height = [pixel_value | device-height] ,
width = [pixel_value | device-width ] ,
initial-scale = float_value ,
minimum-scale = float_value ,
maximum-scale = float_value ,
user-scalable = [yes | no] ,
target-densitydpi = [dpi_value | device-dpi |
high-dpi | medium-dpi | low-dpi]
"
/></span>


2 css控制设备密度
为每种密度创建独立的样式表(注意其中的webkit-device-pixel-ratio 3个数值对应3种分辨率)

html代码
复制代码 代码如下:

<linkrel="stylesheet"media="screen and (-webkit-device-pixel-ratio: 1.5)"href="hdpi.css"/>
<linkrel="stylesheet"media="screen and (-webkit-device-pixel-ratio: 1.0)"href="mdpi.css"/>
<linkrel="stylesheet"media="screen and (-webkit-device-pixel-ratio: 0.75)"href="ldpi.css"/>

在一个样式表中,指定不同的样式

html代码
复制代码 代码如下:

#header {
<spanstyle="white-space: pre"> </span> background:url(medium-density-image.png);
}
@media screen and (-webkit-device-pixel-ratio: 1.5) {
// css for high-density screens
#header {
background:url(high-density-image.png);
}
}
@media screen and (-webkit-device-pixel-ratio: 0.75) {
// css for low-density screens
#header {
background:url(low-density-image.png);
}
}


html代码
复制代码 代码如下:

<metaname="viewport"content="target-densitydpi=device-dpi, width=device-width"/>
[code]
3 js控制
android浏览器和webview支持查询当前设别密度的dom特性
window.devicepixelratio 同样值有3个(0.75,1,1.5对应3种分辨率)
js中查询设备密度的方法
js代码
[code]
if (window.devicepixelratio == 1.5) {
alert("this is a high-density screen");
} elseif (window.devicepixelration == 0.75) {
alert("this is a low-density screen");
}

android中构建html5应用
使用webview控件 与其他控件的使用方法相同 在layout中使用一个<webview>标签
webview不包括导航栏,地址栏等完整浏览器功能,只用于显示一个网页
在webview中加载web页面,使用loadurl()
java代码
复制代码 代码如下:

webview mywebview = (webview) findviewbyid(r.id.webview);
mywebview.loadurl("http://www.example.com");

注意在manifest文件中加入访问互联网的权限:
xml代码
复制代码 代码如下:

<uses-permissionandroid:name="android.permission.internet"/>

在android中点击一个链接,默认是调用应用程序来启动,因此webview需要代为处理这个动作 通过webviewclient
java代码
复制代码 代码如下:

//设置webviewclient
webview.setwebviewclient(new webviewclient(){
publicboolean shouldoverrideurlloading(webview view, string url) {
view.loadurl(url);
returntrue;
}
publicvoid onpagefinished(webview view, string url) {
super.onpagefinished(view, url);
}
publicvoid onpagestarted(webview view, string url, bitmap favicon) {
super.onpagestarted(view, url, favicon);
}
});

这个webviewclient对象是可以自己扩展的,例如
java代码
复制代码 代码如下:

privateclass mywebviewclient extends webviewclient {
publicboolean shouldoverrideurlloading(webview view, string url) {
if (uri.parse(url).gethost().equals("www.example.com")) {
returnfalse;
}
intent intent = new intent(intent.action_view, uri.parse(url));
startactivity(intent);
returntrue;
}
}

之后:
java代码
复制代码 代码如下:

webview mywebview = (webview) findviewbyid(r.id.webview);
mywebview.setwebviewclient(new mywebviewclient());

另外出于用户习惯上的考虑 需要将webview表现得更像一个浏览器,也就是需要可以回退历史记录
因此需要覆盖系统的回退键 goback,goforward可向前向后浏览历史页面
java代码
复制代码 代码如下:

publicboolean onkeydown(int keycode, keyevent event) {
if ((keycode == keyevent.keycode_back) && mywebview.cangoback() {
mywebview.goback();
returntrue;
}
returnsuper.onkeydown(keycode, event);
}

java代码
复制代码 代码如下:

webview mywebview = (webview) findviewbyid(r.id.webview);
websettings websettings = mywebview.getsettings();
websettings.setjavascriptenabled(true);

(这里的websetting用处非常大 可以开启很多设置 在之后的本地存储,地理位置等之中都会使用到)
1 在js中调用android的函数方法
首先 需要在android程序中建立接口
java代码
复制代码 代码如下:

finalclass injavascript {
publicvoid runonandroidjavascript(final string str) {
handler.post(new runnable() {
publicvoid run() {
textview show = (textview) findviewbyid(r.id.textview);
show.settext(str);
}
});
}
}

java代码
复制代码 代码如下:

//把本类的一个实例添加到js的全局对象window中,
//这样就可以使用windows.injs来调用它的方法
webview.addjavascriptinterface(new injavascript(), "injs");
在javascript中调用js代码
function sendtoandroid(){
var str = "cookie call the android method from js";
windows.injs.runonandroidjavascript(str);//调用android的函数
}

2 在android中调用js的方法
在js中的方法:
js代码
复制代码 代码如下:

function getfromandroid(str){
document.getelementbyidx_x_x_x("android").innerhtml=str;
}

在android调用该方法java代码
复制代码 代码如下:

button button = (button) findviewbyid(r.id.button);
button.setonclicklistener(new onclicklistener() {
publicvoid onclick(view arg0) {
//调用javascript中的方法
webview.loadurl("javascript:getfromandroid('cookie call the js function from android')");
}
});

3 android中处理js的警告,对话框等 在android中处理js的警告,对话框等需要对webview设置webchromeclient对象
java代码
复制代码 代码如下:

//设置webchromeclient
webview.setwebchromeclient(new webchromeclient(){
//处理javascript中的alert
publicboolean onjsalert(webview view, string url, string message, final jsresult result) {
//构建一个builder来显示网页中的对话框
builder builder = new builder(mainactivity.this);
builder.settitle("alert");
builder.setmessage(message);
builder.setpositivebutton(android.r.string.ok,
new alertdialog.onclicklistener() {
publicvoid onclick(dialoginterface dialog, int which) {
result.confirm();
}
});
builder.setcancelable(false);
builder.create();
builder.show();
returntrue;
};
//处理javascript中的confirm
publicboolean onjsconfirm(webview view, string url, string message, final jsresult result) {
builder builder = new builder(mainactivity.this);
builder.settitle("confirm");
builder.setmessage(message);
builder.setpositivebutton(android.r.string.ok,
new alertdialog.onclicklistener() {
publicvoid onclick(dialoginterface dialog, int which) {
result.confirm();
}
});
builder.setnegativebutton(android.r.string.cancel,
new dialoginterface.onclicklistener() {
publicvoid onclick(dialoginterface dialog, int which) {
result.cancel();
}
});
builder.setcancelable(false);
builder.create();
builder.show();
returntrue;
};
@override
//设置网页加载的进度条
publicvoid onprogresschanged(webview view, int newprogress) {
mainactivity.this.getwindow().setfeatureint(window.feature_progress, newprogress * 100);
super.onprogresschanged(view, newprogress);
}
//设置应用程序的标题title
publicvoid onreceivedtitle(webview view, string title) {
mainactivity.this.settitle(title);
super.onreceivedtitle(view, title);
}
});

android中的调试
通过js代码输出log信息
js代码
js代码: console.log("hello world");
log信息: console: hello world http://www.example.com/hello.html :82
在webchromeclient中实现onconsolemesaage()回调方法,让其在logcat中打印信息
java代码
复制代码 代码如下:

webview mywebview = (webview) findviewbyid(r.id.webview);
mywebview.setwebchromeclient(new webchromeclient() {
publicvoid onconsolemessage(string message, int linenumber, string sourceid) {
log.d("myapplication", message + " -- from line "
+ linenumber + " of "
+ sourceid);
}
});

以及java代码
复制代码 代码如下:

webview mywebview = (webview) findviewbyid(r.id.webview);
mywebview.setwebchromeclient(new webchromeclient() {
publicboolean onconsolemessage(consolemessage cm) {
log.d("myapplication", cm.message() + " -- from line "
+ cm.linenumber() + " of "
+ cm.sourceid() );
returntrue;
}
});

*consolemessage 还包括一个 messagelevel 表示控制台传递信息类型。 您可以用messagelevel()查询信息级别,以确定信息的严重程度,然后使用适当的log方法或采取其他适当的措施。
html5本地存储在android中的应用
html5提供了2种客户端存储数据新方法: localstorage 没有时间限制 sessionstorage 针对一个session的数据存储
js代码
复制代码 代码如下:

<script type="text/javascript">
localstorage.lastname="smith";
document.write(localstorage.lastname);
</script>
<script type="text/javascript">
sessionstorage.lastname="smith";
document.write(sessionstorage.lastname);
</script>

webstorage的api:
js代码
复制代码 代码如下:

//清空storage
localstorage.clear();
//设置一个键值
localstorage.setitem(“yarin”,“yangfegnsheng”);
//获取一个键值
localstorage.getitem(“yarin”);
//获取指定下标的键的名称(如同array)
localstorage.key(0);
//return “fresh” //删除一个键值
localstorage.removeitem(“yarin”);
注意一定要在设置中开启哦
setdomstorageenabled(true)
在android中进行操作 java代码
//启用数据库
websettings.setdatabaseenabled(true);
string dir = this.getapplicationcontext().getdir("database", context.mode_private).getpath();
//设置数据库路径
websettings.setdatabasepath(dir);
//使用localstorage则必须打开
websettings.setdomstorageenabled(true);
//扩充数据库的容量(在webchromeclinet中实现)
publicvoid onexceededdatabasequota(string url, string databaseidentifier, long currentquota,
long estimatedsize, long totalusedquota, webstorage.quotaupdater quotaupdater) {
quotaupdater.updatequota(estimatedsize * 2);
}
在js中按常规进行数据库操作 js代码
function initdatabase() {
try {
if (!window.opendatabase) {
alert('databases are not supported by your browser');
} else {
var shortname = 'yarindb';
var version = '1.0';
var displayname = 'yarin db';
var maxsize = 100000; // in bytes
yarindb = opendatabase(shortname, version, displayname, maxsize);
createtables();
selectall();
}
} catch(e) {
if (e == 2) {
// version mismatch.
console.log("invalid database version.");
} else {
console.log("unknown error "+ e +".");
}
return;
}
}
function createtables(){
yarindb.transaction(
function (transaction) {
transaction.executesql('create table if not exists yarin(id integer not null primary key, name text not null,desc text not null);', [], nulldatahandler, errorhandler);
}
);
insertdata();
}
function insertdata(){
yarindb.transaction(
function (transaction) {
//starter data when page is initialized
var data = ['1','yarin yang','i am yarin'];
transaction.executesql("insert into yarin(id, name, desc) values (?, ?, ?)", [data[0], data[1], data[2]]);
}
);
}
function errorhandler(transaction, error){
if (error.code==1){
// db table already exists
} else {
// error is a human-readable string.
console.log('oops. error was '+error.message+' (code '+error.code+')');
}
returnfalse;
}

function nulldatahandler(){
console.log("sql query succeeded");
}
function selectall(){
yarindb.transaction(
function (transaction) {
transaction.executesql("select * from yarin;", [], dataselecthandler, errorhandler);
}
);
}
function dataselecthandler(transaction, results){
// handle the results
for (var i=0; i<results.rows.length; i++) {
var row = results.rows.item(i);
var newfeature = new object();
newfeature.name = row['name'];
newfeature.decs = row['desc'];
document.getelementbyidx_x_x_x("name").innerhtml="name:"+newfeature.name;
document.getelementbyidx_x_x_x("desc").innerhtml="desc:"+newfeature.decs;
}
}
function updatedata(){
yarindb.transaction(
function (transaction) {
var data = ['fengsheng yang','i am fengsheng'];
transaction.executesql("update yarin set name=?, desc=? where id = 1", [data[0], data[1]]);
}
);
selectall();
}
function ddeletetables(){
yarindb.transaction(
function (transaction) {
transaction.executesql("drop table yarin;", [], nulldatahandler, errorhandler);
}
);
console.log("table 'page_settings' has been dropped.");
}

注意onload中的初始化工作
复制代码 代码如下:

function initlocalstorage(){
if (window.localstorage) {
textarea.addeventlistener("keyup", function() {
window.localstorage["value"] = this.value;
window.localstorage["time"] = new date().gettime();
}, false);
} else {
alert("localstorage are not supported in this browser.");
}
}
window.onload = function() {
initdatabase();
initlocalstorage();
}

html5地理位置服务在android中的应用
android中java代码
复制代码 代码如下:

//启用地理定位
websettings.setgeolocationenabled(true);
//设置定位的数据库路径
websettings.setgeolocationdatabasepath(dir);
//配置权限(同样在webchromeclient中实现)
publicvoid ongeolocationpermissionsshowprompt(string origin,
geolocationpermissions.callback callback) {
callback.invoke(origin, true, false);
super.ongeolocationpermissionsshowprompt(origin, callback);
}
在manifest中添加权限 xml代码
<uses-permissionandroid:name="android.permission.access_fine_location"/>
<uses-permissionandroid:name="android.permission.access_coarse_location"/>
html5中 通过navigator.geolocation对象获取地理位置信息 常用的navigator.geolocation对象有以下三种方法: js代码
//获取当前地理位置
navigator.geolocation.getcurrentposition(success_callback_function, error_callback_function, position_options)
//持续获取地理位置
navigator.geolocation.watchposition(success_callback_function, error_callback_function, position_options)
//清除持续获取地理位置事件
navigator.geolocation.clearwatch(watch_position_id)
其中success_callback_function为成功之后处理的函数,error_callback_function为失败之后返回的处理函数,参数position_options是配置项 在js中的代码js代码
//定位
function get_location() {
if (navigator.geolocation) {
navigator.geolocation.getcurrentposition(show_map,handle_error,{enablehighaccuracy:false,maximumage:1000,timeout:15000});
} else {
alert("your browser does not support html5 geolocation");
}
}
function show_map(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var city = position.coords.city;
//telnet localhost 5554
//geo fix -82.411629 28.054553
//geo fix -121.45356 46.51119 4392
//geo nmea $gpgga,001431.092,0118.2653,n,10351.1359,e,0,00,,-19.6,m,4.1,m,,0000*5b
document.getelementbyidx_x_x_x("latitude").innerhtml="latitude:"+latitude;
document.getelementbyidx_x_x_x("longitude").innerhtml="longitude:"+longitude;
document.getelementbyidx_x_x_x("city").innerhtml="city:"+city;
}
function handle_error(err) {
switch (err.code) {
case 1:
alert("permission denied");
break;
case 2:
alert("the network is down or the position satellites can't be contacted");
break;
case 3:
alert("time out");
break;
default:
alert("unknown error");
break;
}
}

其中position对象包含很多数据 error代码及选项 可以查看文档
构建html5离线应用
需要提供一个cache manifest文件,理出所有需要在离线状态下使用的资源
例如manifest代码
cache manifest
#这是注释
images/sound-icon.png
images/background.png
clock.html
clock.css
clock.js
network:
test.cgi
cache:
style/default.css
fallback:
/files/projects /projects
在html标签中声明 <html manifest="clock.manifest"> html5离线应用更新缓存机制 分为手动更新和自动更新2种 自动更新: 在cache manifest文件本身发生变化时更新缓存 资源文件发生变化不会触发更新 手动更新: 使用window.applicationcache
js代码
复制代码 代码如下:

if (window.applicationcache.status == window.applicationcache.updateready) {
window.applicationcache.update(); 
}
在线状态检测 html5 提供了两种检测是否在线的方式:navigator.online(true/false) 和 online/offline事件。在android中构建离线应用java代码
//开启应用程序缓存
websettingssetappcacheenabled(true);
string dir = this.getapplicationcontext().getdir("cache", context.mode_private).getpath();
//设置应用缓存的路径
websettings.setappcachepath(dir);
//设置缓存的模式
websettings.setcachemode(websettings.load_default);
//设置应用缓存的最大尺寸
websettings.setappcachemaxsize(1024*1024*8);
//扩充缓存的容量
publicvoid onreachedmaxappcachesize(long spaceneeded,
long totalusedquota, webstorage.quotaupdater quotaupdater) {
quotaupdater.updatequota(spaceneeded * 2);
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网