欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发笔记之探秘WebView

程序员文章站 2022-11-05 15:38:29
概述:            一个显示网页的视图。这个类是你可以滚动自...

概述:
           一个显示网页的视图。这个类是你可以滚动自己的web浏览器或在你的activity中简单地显示一些在线内容的基础。它使用了webkit渲染引擎来显示网页,包括向前和向后导航的方法(通过历史记录),放大和缩小,执行文本搜索等。

         需要注意的是:为了让你的应用能够使用webview访问互联网和加载网页,你必须添加internet的权限在android manifest文件中:

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

类结构:

java.lang.object
  ↳ android.view.view
   ↳ android.view.viewgroup
     ↳ android.widget.absolutelayout
      ↳ android.webkit.webview

常用方法:

websettings
getsettings()
获取设置webview的websettings对象。
void
setwebviewclient(webviewclient client)
设置将接收各种通知和请求的webviewclient。
void
setwebchromeclient(webchromeclient client)
设置chrome处理。

说明:

websettings  getsettings()获取设置webview的websettings对象。

websettings常用方法:

 

方法
说明
setallowfileaccess
启用或禁用webview访问文件数据
setblocknetworkimage
是否显示网络图像
setbuiltinzoomcontrols
设置是否支持缩放
setcachemode
设置缓冲的模式
setdefaultfontsize
设置默认的字体大小
setdefaulttextencodingname
设置在解码时时候用的默认编码
setfixedfontfamily
设置固定使用的字体
setjavascriptenabled
设置是否支持javascript
setlayoutalgorithm
设置布局方式
setlighttouchenabled
设置用鼠标激活被选项
setsupportzoom
设置是否支持变焦

void  setwebviewclient(webviewclient client)

设置将接收各种通知和请求的webviewclient。

webviewclient 常用方法:

 

方法
说明
doupdatevisitedhistory
更新历史记录
onformresubmission
应用程序重新请求网页数据
onloadresource
加载指定地址提供的资源
onpagefinished
网页加载完毕
onpagestarted
网页开始加载
onreceivederror
报告错误信息
onscalechanged
webview发生改变
shouldoverrideurlloading
控制新的连接在当前webview中打开

void  setwebchromeclient(webchromeclient client) 设置chrome处理。

webchromeclient常用方法:

 

方法
说明
onclosewindow
关闭webview
oncreatewindow
创建webview
onjsalert
处理javascript中的alert对话框
onjsconfirm
处理javascript中的confirm对话框
onjsprompt
处理javascript中的prompt对话框
onprogresschanged
加载进度条改变
onreceivedlcon
网页图标更改
onreceivedtitle
网页title更改
onrequestfocus webview
显示焦点

 自定义webview,你可以添加你自己的行为:
创建和设置webchromeclient子类。当一些可能影响浏览器的用户界面发生了,例如,进度更新和javascript警报送到这里(见调试任务)调用这个类。
创建和设置webviewclient子类。当影响内容呈现的事情发生是调用这个类,例如,错误或表单提交。您也可以拦截的url加载到这里(通过shouldoverrideurlloading())。
修改websettings,如以setjavascriptenabled()方式启用javascript。
将java对象通过addjavascriptinterface(object,string)方法注射到webview。 这方法允许您将java对象注入到一个页面的javascript上下文,这样他们可以通过javascript访问的页面。
下面是一个更加复杂的例子,显示错误处理,设置和进展通知:

// let's display the progress in the activity title bar, like the 
// browser appdoes. 
getwindow().requestfeature(window.feature_progress); 
webview.getsettings().setjavascriptenabled(true); 
final activity activity = this; 
webview.setwebchromeclient(new webchromeclient() { 
 public void onprogresschanged(webview view, int progress) { 
  //activities and webviews measure progress with different scales. 
  //the progress meter will automatically disappear when we reach 100% 
  activity.setprogress(progress * 1000); 
 } 
}); 
webview.setwebviewclient(new webviewclient() { 
 public void onreceivederror(webview view, int errorcode, string description, string failingurl) { 
  toast.maketext(activity, "oh no! " + description, toast.length_short).show(); 
 } 
}); 
webview.loadurl("http://developer.android.com/");  

缩放:
        可以通过 设置 websettings.setbuiltinzoomcontrols(boolean) ,启用内置缩放。

注意:使用缩放,如果不是高度或宽度设置为wrap_content可能会导致不确定的行为,应该避免。

cookie 和窗口管理:
        出于显而易见的安全原因,您的应用程序都有自己的缓存,cookie存储等,它不共享浏览器应用程序的数据。

默认情况下,通过html请求打开新的窗口将被忽略。这是确切的它们是被javascript打开还是被目标链接打开。您可以自定义您的webchromeclient提供自己的行为打开多个窗口,并使用你想要的任何方式渲染它们。

webview中构建web应用程序:      
      如果你想提供一个web应用程序(或只是一个网页)作为客户端应用程序的一部分,你可以使用webview做到这一点。webview类是android的view类的一个扩展,它可以让你显示网页作为你的活动布局的一部分。它不包括一个完全开发的web浏览器的任何功能,如导航控件或一个地址栏。所有的webview默认情况下是显示一个web页面。

     一个使用webview的常见的场景:是当你想要在你的应用程序中提供可能需要更新的信息,如一个终端用户协议或用户指南,那么使用webview是很有帮助的。 在你的android应用程序中你可以创建一个包含webview的activity然后用它来显示的在线托管的文档。

    另一个使用webview的常见的场景:是如果你的应用程序提供的数据总是需要从internet上获取,如电子邮件。在这种情况下,你可能会发现它更容易在你的android应用程序,显示所有的用户数据的网页,而不是执行一个网络请求,然后解析​​数据,并渲染它在android的布局,以建立一个webview。相反,你可以设计的专为android设备的网页,然后实施的webview在你的android应用程序加载的网页。

下面将向你展示如何开始使用webview,以及如何做一些额外的事情,比如在你的android应用程序中处理页面导航和从网页上绑定javascript到客户端的代码。

基本用法:
       默认情况下,webview不提供类似浏览器的窗口小部件,不启用javascript和网页错误被忽略。如果你的目的只是显示一些html作为用户界面的一部分,这也许还不错;用户将不再需要与网页进行交互阅读,并且该网页将不需要与用户进行交互。如果你需要一个全面的web浏览器,那么你可能要调用浏览器应用程序来加载url,而不是用webview中显示它。例如:

1)        在你的app中添加一个webview:

<?xml version="1.0" encoding="utf-8"?> 
<webview xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/webview" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
/> 

2)        使用loadurl()方法加载一个web页面:

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

3)        给应用程序添加访问网络的权限:

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

以上就是显示一个最基本的web页面所有的步骤。
在webview中使用javascript :
       如果你计划在你的webview加载网页时使用javascript,你必须为你的webview启用javascript。一旦启用javascript,你还可以创建你的应用程序代码和javascript代码之间的接口。

javascript在webview中默认情况下是被禁用的。你可以通过附加在webview上的websettings启用它。即使用getsettings()获取websettings       ,然后启用使用setjavascriptenabled()方法启用javascript。


 

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

javascript代码绑定到android代码:
        在开发一个web应用程序,专门设计的webview在你的android应用程序中,您可以创建您的javascript代码和客户端android代码之间的接口。例如,您的javascript代码可以在你的android代码中调用一个方法来显示dialog,而不是使用javascriptalert()方法。

       调用addjavascriptinterface()方法绑定一个新的javascript和android代码之间的接口。通过它 一个类实例绑定到你的javascrip,javascript可以调用一个接口名称访问类。

public class webappinterface { 
  context mcontext; 
  /** instantiatethe interface and set the context */ 
  webappinterface(context c) { 
    mcontext = c; 
  } 
  /** show a toastfrom the web page */ 
  @javascriptinterface 
  public void showtoast(string toast) { 
    toast.maketext(mcontext, toast, toast.length_short).show(); 
  } 
} 

注意:如果你设置的targetsdkversion为17或更高,则必须添加@javascriptinterface为任何您想要提供给您的javascript(该方法必须是public)方法添加标注。如果你不提供注解,在android4.2或更高版本上运行时该方法是不能被网页访问的。
       在上面这个例子中,webappinterface 类允许网页调用showtoast()方法创建一个toast 消息。

      你可以通过addjavascriptinterface()方法和android接口名,绑定这个类到运行在你的webview中的javascript上。

webview webview = (webview) findviewbyid(r.id.webview); 
webview.addjavascriptinterface(new webappinterface(this), "android"); 

 

         这将为运行在webview中的javascript创建一个名为android的接口。在这一点上,web应用程序可以访问webappinterface类。例如,下面是一些html和javascript在单击按钮的时候将创建一个toast消息。

<input type="button" value="sayhello" onclick="showandroidtoast('hello android!')" /> 
<script type="text/javascript"> 
  function showandroidtoast(toast) { 
    android.showtoast(toast); 
  } 
</script> 

这不需要从javascript接口初始化android。 webview自动的将它应用到你的web页面中。 因此,按下按钮showandroidtoast()方法使用android接口调用webappinterface.showtoast()方法。
注:绑定到你的javascript对象运行在另一个线程,而不是在它构建的线程。

警告:使用addjavascriptinterface()将允许 javascript来控制你的android应用程序。 这是一个非常有用的特性或危险的安全问题。 当webview的html是不值得信任的(例如,部分或全部的html是由一个不知名的人或进程提供的),那么攻击将者执行包括在html和选择的任何客户端代码。因此,不应该使用addjavascriptinterface()除非你写的所有html和javascript出现在你webview。 你应该也不允许用户导航到其他不是自己的网页,,在你的webview内(相反,允许用户的通过默认浏览器应用程序打开外部链接。应用的web浏览器打开所有的url链接,所以要小心你只有在处理页面导航中描述以下部分)。

处理页面导航:
      当用户单击在webview上的链接时,默认行为是启动一个处理url的android应用。通常默认网页浏览器打开和装在目的url。但是你可以为webview覆盖这个行为,以便在你的webview上打开链接。然后,您可以允许用户前后浏览通过的由您的webview保留的网页历史记录。

要打开用户点击链接,只是提供一个webviewclient为您的webview,使用setwebviewclient()。

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

这样。用户点击的所有的链接,都在你的webview上加载。
如果你想更多的控制点击链接的加载,创建自己的webviewclient的覆盖shouldoverrideurlloading()方法。

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 anotheractivity that handles urls 
    intent intent = new intent(intent.action_view, uri.parse(url)); 
    startactivity(intent); 
    return true; 
  } 
} 

然后为webview创建一个新的webviewclient实例:

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

      现在,当用户点击一个链接时,系统调用shouldoverrideurlloading(),它会检查url主机是否一个特定的域相匹配(定义如上)。如果不匹配,那么为了不重写的url加载(它允许webview加载的url照常)方法返回false。如果url中的主机不匹配,那么 一个intent将被创建启动默认的activity 处理url(它可以解决用户的默认web浏览器)。
浏览网页的历史记录:
     当你的webview重载url加载的时,webview会自动累加访问过的网页的历史记录。您可以通过goback()和 goforward()方法向后、向前浏览。

@override 
public boolean onkeydown(int keycode, keyevent event) { 
  // check if thekey event was the back button and if there's history 
  if ((keycode == keyevent.keycode_back) && mywebview.cangoback()) { 
    mywebview.goback(); 
    return true; 
  } 
  // if it wasn'tthe back key or there's no web page history, bubble up to the default 
  // systembehavior (probably exit the activity) 
  return super.onkeydown(keycode, event); 
} 

     如果有一个实际的网页历史记录用户访问的cangoback()方法返回true。同样地,你可以使用cangoforward()来检查是否有历史前进。如果不执行此检查,那么一旦用户到达历史的终结,goback()或goforward()什么也不做。