小猪的Android入门之路
Day 8 part 5
Android网络编程浅析――WebView浏览器编程初涉
――转载请注明出处:coder-pig
本节引言:
不知不觉Android网络编程浅析也快接近尾声了,在这part中我们学习了很多关于android
在网络方面的编程,现在我们来回顾一下吧!
part 1:xml文件的简单了解:以及android中解析xml文件的一些常用方式:sax,dom,pull解析xml
part 2:Android访问网络资源:HTML协议,获取图片,获取网页代码,解析服务器返回的xml数据,
解析服务器返回的JSON数据
part 3:Android网络数据的下载:J2SE单线程下载文件,J2SE普通多线程下载文件
Android多线程断点下载
part 4:Android网络数据的上传:GET或POST方式上传数据;开源框架HttpClient上传数据;
发送xml数据给服务;通过Http协议上传文件;WebService平台的了解以及简单应用
而在Part 5中为大家讲解的是Android中提供的一个组件:WebView(网络视图)的讲解,相比起前面
的内容来说,就容易很多了,那么,就跟随笔者的脚步来学习WebView的使用吧!
本节学习路线图:
笔者要上课,上完回去发哈
正文:
什么是WebView?
怎么用WebView?
①直接在Activity中调用WebView:
详细代码如下:
package com.jay.example.webviewdemo1;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private WebView wView;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wView = new WebView(this); //①实例化WebView对象
wView.setWebViewClient(new WebViewClient() //②设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
wView.getSettings().setJavaScriptEnabled(true); //③设置WebView属性,运行执行js脚本
wView.loadUrl("http://www.baidu.com/"); //④调用loadView方法为WebView加入链接
setContentView(wView); //⑤调用Activity提供的setContentView将webView显示出来
}
//⑥另外还需要重写回退按钮的方法,不然,当我们在WebView中点击多个页面后,一按回退就退出程序了的
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && wView.canGoBack()) {
wView.goBack(); //goBack()表示返回WebView的上一页面
return true;
}
return false;
}
}
效果图:
②在布局代码中设置WebView
这个其实和在Activity中直接设置的差别不大,代码都差不多;
另外在第一个代码中并没有深入的对回退按钮的点击事件只是
设置了webView的回退,相信细心的读者已经发现,这个程序无论你怎么
按都是退出不了程序的,哈哈!所以在demo2中给出处理方案;
当webView不能再回退,再设置点击两次后退出app,详情见代码
布局代码:activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.webviewdemo2.MainActivity" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editurl"
android:hint="请输入要访问的Url"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnload"
android:text="浏览"
/>
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webview"
/>
</LinearLayout>
MainActivity.java
package com.jay.example.webviewdemo2;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText editurl;
private Button btnload;
private WebView webView;
private String strurl;
//定义一个用来存储点击退出按钮时间的便利
private long exitTime = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editurl = (EditText) findViewById(R.id.editurl);
btnload = (Button) findViewById(R.id.btnload);
webView = (WebView) findViewById(R.id.webview);
//设置WebView属性,能够执行Javascript脚本
webView.getSettings().setJavaScriptEnabled(true);
//设置Web视图
webView.setWebViewClient(new MyWebViewClient());
btnload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
strurl = editurl.getText().toString();
//如果用户输入的url不带有http://是找不到网页的哦!
if(!strurl.startsWith("http://"))
{
strurl = "http://" + strurl;
}
webView.loadUrl(strurl);
}
});
}
//当我们在webView上打开多个网页后,我们会习惯性地按回退键
//这个时候我们需要重写回退键按钮,当点击后调用的是WebView的goBack方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK)
{
if(System.currentTimeMillis() - exitTime > 2000)
{
if(webView.canGoBack())
{
webView.goBack();
}
else
{
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
}
}
else
{
System.exit(0);
}
}
return false;
}
//Web视图,继承WebViewClient,重写shouldOverrideUrlLoading方法
//这样做的话可以避免我们点击了WebView中某个链接,继续在该WebView窗口上打开网页
//而不是开启手机自身的broswer来打开链接
class MyWebViewClient extends WebViewClient
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
效果图:
WebView常用的相关方法:
WebView常用方法:
getSettings()
|
返回一个WebSettings对象,用来控制WebView的属性设置
|
loadUrl(String url)
|
加载指定的Url |
loadData(String data,String mimeType,String encoding)
|
加载指定的Data到WebView中.使用"data:"作为标记头,
改方法不能加载网络数据.其中mimeType为数据类型如:textml,image/jpeg.
encoding为字符的编码方式
|
setWebViewClient(WebViewClient client)
|
为WebView指定一个WebViewClient对象.WebViewClient可
以辅助WebView处理各种通知,请求等事件。
|
setWebChromeClient(WebChromeClient client)
|
为WebView指定一个WebChromeClient对象,WebChromeClient专门用来辅助WebView处理js的对话框,网站title,网站图标,加载进度条等
|
WebSettings的常用方法:
setJavaScriptEnabled(boolean flag)
|
设置是否支持JavaScript
|
setDefaultFontSize(int size)
|
设置默认的字体大小 |
setDefaultTextEncodingName(String
encoding)
|
设置默认字符的编码方式
|
setAllowFileAccess(boolean allow):
|
设置是否允许访问文件数据
|
setDatabaseEnabled(boolean flag)
|
设置是否可以使用数据库相关的api
|
setDatabasePath(String databasePath) |
若使用数据库API,该方法指定数据库文件的路径 |
setBlockNetworkImage(boolean flag) |
设置是否禁止显示图片,true表示禁止图片 |
setSavePassword(boolean save) |
设置是否保存密码 |
setTextize(WebSetting.TextSize) |
设置页面文字大小 |
setSupportZoom(bollean support) |
设置是否支持变焦 |
WebViewClient的常用方法
onPageStared(WebView view,String url) |
通知主程序网页开始加载 |
onPageFinished(WebView view,String url,Bitmap favicon)
|
通知主程序,网页加载完毕 |
doUpdateVisitedHistory(WebView view,String url,boolean isReload)
|
更新历史记录 |
onLoadResource(WebView view,String url)
|
通知主程序WebView即将加载指定url的资源 |
onScaleChanged(WebView view,float oldScale,float newScale)
|
ViewView的缩放发生改变时调用 |
shouldOverrideKeyEvent(WebView view,KeyEvent event) |
控制webView是否处理按键时间,如果返回true
则WebView不处理,返回false则处理 |
shouldOverrideUrlLoading(WebView view,String url) |
控制对新加载的Url的处理,返回true,说明主程序处理
WebView不做处理,返回false意味着WebView会
对其进行处理 |
onReceivedError(WebView view,int errorCode,String description,
String failingUrl) |
遇到不可恢复的错误信息时调用 |
WebChromeClient的常用方法
onJsAlert(WebView view,String url,String message,JsResult result) |
处理Js中的Alert对话框 |
onJsConfirm(WebView view,String url,String message,JsResult result)
|
处理Js中的Confirm对话框 |
onJsPrompt(WebView view,String url,String message
String defaultValue,,JsPromptResult result)
|
处理Js中的Prompt对话框 |
onProgressChanged(WebView view,int newProgress)
|
当加载进度条发生改变时调用 |
使用WebView中的js调用Android方法:
在开始讲解这里之前,相信大家都知道webView是一个类似于浏览器的组件了,他就是用来加载网页的;
但是它真的只有加载网页那么简单么?答案肯定是否定的;首先大家都知道HTML是拿来做静态网站的吧
但是Android的界面开发可以采用HTML网页技术,相比起我们用Layout技术慢慢布局显得更加方便,快捷
当然,屏幕适配是需要解决的问题;另外在我们的HTML中需要获取Android设备的相关信息时,比如获取设备
所在的经纬度(定位),或者读取联系人,打电话,发送信息等的!而实现互访的原理如下:
html――js――java,就是说以js为媒介,只需要传递JSon类型的数据即可!
注意:为了节省篇幅.以下代码使用的html文件都是放到assets目录下的,访问时
直接用loadUrl("file:///android_asset/~")即可
代码示例:
①html通过js显示Toast与普通列表的对话框
效果图:
核心代码:
自定义一个Object对象,js通过该类暴露的方法来调用Android
MyObject.java:
package com.jay.example.webviewdemo3;
import android.app.AlertDialog;
import android.content.Context;
import android.widget.Toast;
public class MyObject {
Context context;
public MyObject(Context context) {
this.context = context;
}
//将显示Toast和对话框的方法暴露给JS脚本调用
public void showToast(String name)
{
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
}
public void showDialog()
{
new AlertDialog.Builder(context)
.setTitle("联系人列表").setIcon(R.drawable.ic_launcher)
.setItems(new String[]{"小王","小坏","小猪","小狗","小猫"}, null)
.setPositiveButton("确定", null).create().show();
}
}
创建一个html文件,内容如下,接着把它放到工程的assets目录下:
my.html
<!DOCTYPE html>
<html>
<head>
<title>Js调用Android</title>
</head>
<body>
<input type="button" value="Toast提示" onclick="myObj.showToast('逗比');"/>
<input type="button" value="列表对话框" onclick="myObj.showDialog();"/>
</body>
</html>
在MainActivity中完成WebView的初始化,设置运行调用js,最后通过addJavascriptIntefcae()将
对象暴露给Js,js就可以通过该对象操作与Android相关的操作了
package com.jay.example.webviewdemo3;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class MainActivity extends Activity {
private WebView webView;
@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///android_asset/my.html");
WebSettings webSettings = webView.getSettings();
//①设置WebView允许调用js
webSettings.setJavaScriptEnabled(true);
webSettings.setDefaultTextEncodingName("UTF-8");
//②将object对象暴露给Js,调用addjavascriptInterface
webView.addJavascriptInterface(new MyObject(MainActivity.this), "myObj");
}
}
ps:上述代码在4.2及以上的虚拟机上都是运行后都是没有点击效果的,
笔者也不知道为什么,但是在真机上都是可以的!
②HTML通过js调用三种不同的对话框
效果图:
核心代码:
创建一个html文件,然后把它放到工程的assets目录下:
my.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv = "Content-Type" content="text/html;charset=UTF-8"
<title>测试Js的三种不同对话框</title>
<script language="JavaScript">
function alertFun()
{
alert("Alert警告对话框!");
}
function confirmFun()
{
if(confirm("访问百度?"))
{location.href = "http://www.baidu.com";}
else alert("取消访问!");
}
funct
------分隔线----------------------------
------分隔线----------------------------