前一段时间看了一下WebView的内容,自己试着写了几个小的程序。现在进行一下个人的小结,为了以后自己忘记的时候还可以看看。
在Android系统中内嵌了一个高性能的webkit内核浏览器,在SDK中封装为一个叫做WebView组件,通过这个组件可以像浏览器一样地去解析网页。使用的时候可以直接加载网址进行浏览。
那么什么是webkit?官方的解释是:WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。 传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过, 随着JavaScript引擎的独立性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,却仍然宣称自己是WebKit内核)。
不理解这些也不耽误我们去使用的,这里就以一个自己写的小程序来说一下。这里先看一下完成之后的截图(做的不好,主要是为了讲解)
第一个是打开后的第一个页面,是要输入网址的,第二个是输入的网址,第三个是加载之后的页面。
下面是代码的介绍
- 布局文件
这个程序有两个Activity,第一个输入网址的是第一个Activity,第二个Activity是含有WebView组件的用来加载网页的(第三个图片),下面是第一个Activity的布局文件,文件名是startactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableRow>
<EditText
android:id="@+id/edittext"
android:layout_weight="0.7"
android:text="输入网址" />
<Button
android:layout_weight="0.3"
android:text="Load"
android:id="@+id/btn"
/>
</TableRow>
<TableRow>
<TableLayout>
<TableRow>
<Button
android:text="http://"
android:layout_weight="0.25"
android:id="@+id/http"
/>
<Button
android:text="www."
android:layout_weight="0.25"
android:id="@+id/www"
/>
<Button
android:text=".com"
android:layout_weight="0.25"
android:id="@+id/com"
/>
<Button
android:text="清空"
android:layout_weight="0.25"
android:id="@+id/clear"
/>
</TableRow>
</TableLayout>
</TableRow>
</TableLayout>
第二个Activity的布局文件,文件名activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
第三个是AndroidMainifset文件,这个有一个要注意的地方,要给添加了WebView之间的Activity添加访问网络的权限,在第9行
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.webview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.webview.MainActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.example.webview.StartActivity"
android:label="@string/start_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
第一个比较简单,我们直接看第二个,WebView的使用方式和其他的控件类似,它的一些常用属性如下
setAllowFileAccess 启用或禁止WebView访问文件数据
setBlockNetworkImage 是否显示网络图像
setBuiltInZoomControls 设置是否支持缩放
setCacheMode 设置缓冲的模式
setDefaultFontSize 设置默认的字体大小
setDefaultTextEncodingName 设置在解码时使用的默认编码
setFixedFontFamily 设置固定使用的字体
setJavaSciptEnabled 设置是否支持Javascript
setLayoutAlgorithm 设置布局方式
setLightTouchEnabled 设置用鼠标激活被选项
setSupportZoom 设置是否支持变焦
WebViewClient常用方法:
doUpdate VisitedHistory 更新历史记录
onFormResubmission 应用程序重新请求网页数据
onLoadResource 加载指定地址提供的资源
onPageFinished 网页加载完毕
onPageStarted 网页开始加载
onReceivedError 报告错误信息
onScaleChanged WebView发生改变
shouldOverrideUrlLoading 控制新的连接在当前WebView中打开
WebChromeClient常用方法:
onCloseWindow 关闭WebView
onCreateWindow 创建WebView
onJsAlert 处理Javascript中的Alert对话框
onJsConfirm处理Javascript中的Confirm对话框
onJsPrompt处理Javascript中的Prompt对话框
onProgressChanged 加载进度条改变
onReceivedlcon 网页图标更改
onReceivedTitle 网页Title更改
onRequestFocus WebView显示焦点
这个具体的使用大家可以百度,这些的用法是前端的要考虑的,我们这里只是讲解用法。
- 主程序代码
第一个是startactivity的代码,文件名 StartActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class StartActivity extends Activity implements OnClickListener
{
private EditText editText;
private Button button,button2,button3,button4,button5;
String webadress;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.startactivity);
editText=(EditText)findViewById(R.id.edittext);
button=(Button)findViewById(R.id.btn);
button2=(Button)findViewById(R.id.http);
button3=(Button)findViewById(R.id.www);
button4=(Button)findViewById(R.id.com);
button5=(Button)findViewById(R.id.clear);
button.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
button5.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn:
{
webadress=(String)editText.getText().toString();
Intent intent=new Intent();//新建一个意图对象
intent.setClass(StartActivity.this, MainActivity.class);
//传递键值为adress的字符串,在打开另一个的Activity中可以进行接收
intent.putExtra("adress", webadress);
startActivity(intent);
webadress=null;
break;
}
case R.id.http:
{//获取光标位置
int index = editText.getSelectionStart();
//是一个公共的接口类型,可以变化,具体详见introduce.txt文档
Editable editable = editText.getText();
//在index位置进行添加内容
//editable.delete(index-1, index);删除index位置前一个字符
editable.insert(index, "http://");
break;
}
case R.id.www:
{
int index = editText.getSelectionStart();
Editable editable = editText.getText();
editable.insert(index, "www.");
break;
}
case R.id.com:
{
int index = editText.getSelectionStart();
Editable editable = editText.getText();
editable.insert(index, ".com");
break;
}
case R.id.clear:
{
editText.setText("");
break;
}
default:
break;
}
}
}
第二个是MainActivity的代码,文件名 MainActivity.java
import android.os.Bundle;
import android.R.string;
import android.app.Activity;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MainActivity extends Activity {
private WebView webView;//声明WebView对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);//这个是设置WebView自带的进度条,可以了解一下
setContentView(R.layout.activity_main);
//由于这个程序使用两个Activity,这下面的一段是用来接收上一个Activity传过来的网址的
Intent intent=getIntent();//新建Intent对象,用于上一个Activity数据的接收
Bundle bundle=intent.getExtras();
final String str=bundle.getString("adress");//得到键值为adress的字符串
webView=(WebView)findViewById(R.id.webview);
//设置处理网页中的JavaScript为真
//当网页中有js的时候可以进行简单的处理
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(true);//支持缩放
webView.getSettings().setBuiltInZoomControls(true);//启用内置缩放装置
//这个WebViewClient是用来解析,渲染网页的,具体的用法在之后的introduce.txt有说明
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO Auto-generated method stub
//Activity和WebView决定加载的进度条,加载到100%时,进度条消失
//该进度条是在标题栏的上方
setTitle(str);//设置标题栏的内容
setProgress(newProgress*100);
//当newprogress为100的时候,停止
// super.onProgressChanged(view, newProgress);
}
});
//加载页面,网址是str,这个是由上一个Activity传过来的
webView.loadUrl(str);
webView.setWebViewClient(new MyWebViewClient());
}
//处理按键的响应,这个是用来返回上一个浏览的页面的
@Override
public boolean onKeyDown(int keyCode,KeyEvent event)
{
if(keyCode==KeyEvent.KEYCODE_BACK)
{//调用cangoback函数来判断是否有上一个网页
if (webView.canGoBack())
{//调用goback函数,返回上一个网页
webView.goBack();
return true;
}else finish();//如果已经是最后一个页面的话,会退出程序
}
return false;
}
//自定义的视图类, 当点击链接时,希望是覆盖当前而不是打开一个新的页面,WebViewClient就是帮助WebView处理各种通知、请求事件的。具体解释后面介绍
private class MyWebViewClient extends WebViewClient
{
//函数的重载,检测网络的连接
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "网络连接失败 ,请连接网络。", Toast.LENGTH_SHORT).show();
super.onReceivedError(view, errorCode, description, failingUrl);
}
//这个是设置当点击网页上的链接时,是在这个页面进行显示,不会调用手机默认的浏览器进行加载,当不设置的时候,点击会打开手机的默认浏览器
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
}
}
一些代码的解释在注释中已经给出,下面是introduce.txt文档
1.Editable
Editable 是一个接口类型,对它的实例化对象作出任何改变都是对原有的实例化对象操作的,内存地址还是原来的那个。
而对 String 的任何改变都是相当于重新实例化了一个 String 类出来,相当于重新分配了内存地址。
所以说 Editable 是可变的,String 是不可变的了;因为 Editable 变了之后还是原来的 Editable 对象,
String 变了之后就已经不是原来的 String 对象了。
2.setWebChromeClient和setWebViewClient的区别
android.webkit库聚合了webkit内核的浏览器功能,webview就是她的一个控件,可以使得网页轻松的内嵌到app里。
并且比较强大的是,还可以直接跟js相互调用。
webview有两个方法:setWebChromeClient和setWebClient
setWebChromeClient主要处理解析,渲染网页等浏览器做的事情
WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等
onCloseWindow(关闭WebView)
onCreateWindow()
onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
比如可以添加进度条,使得界面更友好
webview1.setWebChromeClient(new WebChromeClient()
{
public void onProgressChanged(WebView view, int progress)
{
setProgress(progress * 100);
if(progress == 100){
imageView1.setVisibility(View.GONE);
tv1.setVisibility(View.GONE);
pb1.setVisibility(View.GONE);
fy1.setVisibility(View.GONE);
}
}
}
);
WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
例如:
webview1.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{ // Handle the error
Toast.makeText(getApplicationContext(), "网络连接失败 ,请连接网络。", Toast.LENGTH_SHORT).show();
}
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); //设置字符集编码
webview1.getSettings().setDefaultTextEncodingName("UTF-8");
webview1.loadUrl("http://www.android100.org/");
基本的介绍就是这些了,