Android WebView的使用
使用WebView浏览网页
WebView组建是一个浏览器的实现,可以使得网页能够轻松内嵌到app里,同时还可以直接跟js相互调用。
WebView有两个重要方法:
setWebViewClient
辅助WebView处理各种通知和请求。
setWebChromeClient
辅助WebView处理JavaScript的对话框,网站图标,网站title,加载进度条等。
下面以一个例子演示如何使用WebView浏览网页:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/myUrl"
android:layout_width="wrap_content"
android:layout_weight="1"
android:text="www.baidu.com"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索"
android:id="@+id/mySearch"/>
</LinearLayout>
<WebView
android:id="@+id/myWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"></WebView>
</LinearLayout>
这是页面的布局文件,包含一个输入框和一个搜索按钮,其余部分为WebView所用。
public class MainActivity extends Activity {
private WebView myWebView;
private EditText myUrl;
private Button mySearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myUrl = (EditText) findViewById(R.id.myUrl);
myWebView = (WebView) findViewById(R.id.myWebView);
mySearch = (Button) findViewById(R.id.mySearch);
mySearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String url = "http://" + myUrl.getText().toString();
myWebView.loadUrl(url);
}
});
myWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
}
因为WebView默认会调用第三方应用打开我们传入的地址,因此我们需要在setWebViewClient中重写shouldOverrideUrlLoading方法,该方法如果返回true,则会调用WebView打开网页,否则会询问调用第三方浏览器打开。
同时我们需要在AndroidManifest.xml中加入网络的权限:
<uses-permission android:name="android.permission.INTERNET"/>
这样我们在EditText中输入地址后点击搜索按钮就能够打开网页了。
加载本地资源和网络资源的用法基本相同,不过本地文件的URL格式为:
String file_path = "file://"+ Environment.getExternalStorageDirectory()+"/svg/115.html";
myWebView.loadUrl(file_path);
同时需要加入读写SD卡的权限。
如果我们加载的网页中有JavaScript,则WebView必须设置支持JavaScript,还可以对是否能够缩放等功能进行设置。
WebSettings webSettings = myWebView.getSettings();
webSettings.setLoadWithOverviewMode(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
webSettings.setSupportMultipleWindows(true);
其他常用方法的使用:
1.通过前进后退控制已访问过的站点。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK)
{
if(myWebView.canGoBack())
{
myWebView.goBack();//返回上一页面
return true;
}
else
{
System.exit(0);//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
这样当我们点击返回按钮时就可以返回(goBack())到之前记录的页面,前进方法(goForward())同理,同时还可以控制页面的放大缩小,zoomIn放大页面,zoomOut缩小页面;
2.判断网页的加载过程
myWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if(newProgress == 100){
//网页加载完成
}else{
//正在加载
}
}
});
通过该方法可以对页面的加载进度进行控制。
3.缓存的使用
优先使用缓存:
WebSettings webSettings = myWebView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
不使用缓存:
WebSettings webSettings = myWebView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
使用WebView加载Html代码
WebView可以对HTML字符串进行解析,当成HTML页面进行显示。
WebView提供了loadData方法和loadDataWithBaseURL方法帮助我们加载并显示HTML代码。
loadData(String data, String mimeType, String encoding)
loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl)
data: 指定需要加载的HTML代码,使用loadData时,在数据里面不能出现英文字符:’#’, ‘%’, ‘\’ , ‘?’ 这四个字符,如果有的话可以用 %23, %25, %27, %3f,这些字符来替换。loadDataWithBaseURL则没有这些限制。
mimeType:指定HTML代码的MIME类型,对于HTML代码可指定为text/html
encoding:制定HTML代码编码所用的字符集。比如指定为utf-8或者GBK。
baseUrl/historyUrl:可以理解为标识当前的页面的,相当于为我们解析的HTML页面加一个路径,historyUrl则用于历史记录进行使用,这样当我们使用前进或者后退的时候就能够找到我们解析的页面和设置的历史页面。
当我们在实际使用的时候发现使用loadData方法,如果data中有中文的话,会出现乱码,因此尽量使用loadDataWithBaseURL;
下面我们来看一下使用WebView对Html进行解析:
private void loadMyHtml(){
StringBuilder sb = new StringBuilder();
sb.append("<html>");
sb.append("<head>");
sb.append("<title>hello world</title>");
sb.append("</head>");
sb.append("<body>");
sb.append("<h2>hello world<a herf=\"http//:www.baidu.com\">北京欢迎您!</a></h2>");
sb.append("</body>");
sb.append("</html>");
//会出现乱码
// myWebView.loadData(sb.toString(),"text/html","utf-8");
myWebView.loadDataWithBaseURL(null,sb.toString(),"text/html","utf-8",null);
}
使用javascript调用Android方法
很多页面是带有JavaScript脚本的,例如页面上有一个按钮,点击按钮可能弹出一个对应的信息框,包括alert,comfirm,prompt等,comfirm和prompt在WebView中使用的时候WebChromeClient会默认返回false,也就是页面会自行处理这些js信息,但是alert比较特殊,如果我们需要页面自动处理其alert信息,那么我们需要返回false,这样点击页面中的按钮才能显示出自带的alert信息,这些方法如果返回true,则意味着这些方法会交给客户端进行处理。
myWebView.setWebChromeClient(new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
}
如上代码所示,当我们需要网页显示alert信息的时候,应该重写WebChromeClient中的onJsAlert方法。
当我们需要需要使用js调用Android的方法时,WebView提供了配套的WebSettings工具类,该工具类中有大量方法来对WebView进行设置,其中的setJavaScriptEnabled方法可以设置WebView是否能够执行js脚本,当我们需要通过js调用android方法时,首先应该设置该方法为true。其次,WebVIew提供了一个addJavascriptInterface(Object object,String name)方法,该方法用于将Object对象暴露成js中的name对象。最后只需要在js中通过name对象调用android方法即可。
使用方法如下所示:
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new MyObject(MainActivity.this), "myObj");
首先我们开启对JavaScript脚本的支持。然后在webview的addJavascriptInterface传入我们在Android代码中自定义的MyObject类,该方法将MyObject对象暴露给js脚本,并且在js脚本中将其命名为myObj,这样我们就可以通过该命名即myObj来调用MyObject中的方法了。
public class MyObject {
private Context context;
public MyObject(Context context){
this.context = context;
}
@JavascriptInterface
public void showToast(String name){
Toast.makeText(context,name,Toast.LENGTH_SHORT).show();
}
}
MyObject方法为我们自定义的Java类,对于我们需要暴露的方法需要使用@JavascriptInterface修饰符进行修饰,这样在js脚本中才能够使用。
最后我们在js中进行调用即可,如下代码所示:
<html>
<head>
<title>hello</title>
</head>
<body>
<input type="button" value="弹出信息" onclick="myObj.showToast('hello world');" />
</body>
</html>
通过如上所示流程我们就可以在js中调用Android本地的方法了。
使用Android调用javascript中的方法
使用Android调用javascript的方法就比较简单了,只需要在url中加入javascript:即可,如下所示:
String url = "javascript:changeBackGround();";
webView.loadUrl(url);
例如html页面中的javascript中有一个changeBackGround()的方法,只需按照上面所示即可调用,当然也可以直接写入js代码,但是在测试的时候发现容易出现问题,就不在赘述。