(written in 2012-08-09 22:31:31)
WebKit的组成
- Webkit :整个项目的名称
- JavaScriptCore:JavaScript解析器
-
- API:基本JavaScript功能
- Binding:与其他功能的绑定,如DOM,C,JNI
- DerviedSource:自动生成代码
- ForwordHeads:头文件,无实际意义
- PCRE:Perl-Compatible Regular Expressions(Perd兼容的规则表达式)
- KJS:Javascript内核
- WTF:KDE的C++模板库
- WebCore:整个项目的核心,实现Render引擎,解析web页面,生成一个DOM树和一个Render树
-
- Page:与外界相关的内容。Frame,Page,History,Focus,Windows
- Loader:加载资源及Cache
- HTML:DOM HTML内容及解析
- DOME: DOM CORE内容
- XML:XML内容及解析
- Render:排版功能
- CSS:DOM CSS内容
- Binding:DOM与JavaScriptCore绑定的功能
- Editing:所有与编辑相关的功能
WebView:用于浏览网页,是一个功能齐全的移动设备浏览器。
WebSettings:管理网页试图的各种设置。
WebViewClient:用于接收来自网页试图的各种消息和请求。
WebChromeClient:用于辅助WebView处理JavaScript的对话框,网站图片,网站Title,加载程度等等。
OnTouchListener接口:该接口负责处理用户触摸手机中WebView所在区域的事件。
Webkit的解析流程
- CURL获得网站的stream
- 解析划分字符串
- 通过DOM Builder按合法的HTML规范生成DOM树
- 如果有JavaScript,JSEngine就通过ECMA-262保准完善DOM树
- 把DOM传给LayoutEngine进行布局,如果有CSS样式,就通过CSSParser解析
- 最后Rendering渲染出来
常用方法
- setWebViewClient() 创建一个客户端浏览器对象
例:webView.setWebViewClient(new WebViewClient());
- setWebChromeClient() 创建一个WebChromeClient对象
例:webView.setWebChromeClient(new WebChromeClient());
- getSetting() 创建WebSetting对象
例:WebSettings webSettings = webView.getSettings();
- loadUrl() 载入指定网址的网页
例:webView.loadUrl("www.google.com");
调用javaScript webView.loadUrl("javascript:xxx' "+param+" ' ");
- addJavascriptInterface(Object obj,String interfaceName);
作用:设置JavaScript接口,允许网页中的JavaScript函数调用Java中的方法。
参数obj:自定义的类的实力;参数interfaceName:设置代表第一个参数所在类的名称,该名称将在JavaScrpit中被使用。
例:
addjavascriptInterface(new MyClass,"aaa");
class MyClass{
public void runOnJs(String message){
Message msg = new Message();
msg.obj = message;
mHandler.sendMessage(msg);
}
}
在JavaScript中调用runOnJs:
window.aaa.runOnJs(str);
- webSetting.setJavaScriptEnabled(Boolean enable) 设置是否支持JavaScrpit脚本。
- webChromeClient.onProgressChanged() 加载进度条改变时调用
- webChromeClient.RequestFocus() 设置WebView获取焦点
WebView控件的使用
<WebView
android:id="@+id/webview01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
andorid:layout_weight="1"
/>
例:网页加载时,显示加载进度条,用户触摸网页时,网页获得焦点
WebView mWebView = (WebView)findViewById(R.id.wv);
mWebView.requestFocus(); //设置页面焦点
mWebView.loadUrl("10.0.2.2/android.html");
mWebView.setWebChromeClient(new WebChromeClient(){
public void onProgressChnaged(WebView view,int newProgress){
super.onProgressChanged(view,newProgress);
mProgressBar.setProgress(newProgress);
}
});
//设置网页触摸监听事件
mWebView.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v,MotionEvent event){
mWebView.requestFocus(); //设置网页获得焦点
return false;
}
});
WebSetting
WebSetting用来设置WebView的属性,状态。在创建WebView时,系统有一个默认的设置,通过WebView.getSettings来得到这个设置:
WebSettings webSettings = mWebView.getSettings();
常用API
setAllowFileAccess | 启动或禁止WebView访问文件数据 |
setBlockNetworkImage | 是否显示网络图像 |
setBuiltInZoomControls | 设置是否支持缩放 |
setCacheMode | 设置缓冲模式 |
setDefaultFontSize | 设置默认字体大小 |
setDeafaultTextEncodingName | 设置在解码时使用的默认编码 |
setFixedFontFamily | 设置固定使用的字体 |
setJavaScriptEnabled | 设置是否支持JavaScript |
setLayoutAlgorithm | 设置布局方式 |
setLightTouchEnabled | 设置用鼠标激活被选项 |
setSupportZoom | 设置是否之支持变焦 |
WebViewClient
专门辅助WebView处理各种通知、请求等事件的类。
使得当有新的连接时,使用的那个钱的WebView来显示:
public boolean shouldOverrideUrlLoading(WebView view,String url){
view.loadUrl(url);
return true;
}
常用的方法
doUpdateVisitedHistory | 更新历史记录 |
onFormResubmission | 应用程序重新请求网页数据 |
onLoadResource | 加载指定地址提供的资源 |
onPageFinished | 网页加载完毕 |
onPageStarted | 网页开始加载 |
onReceivedError | 报告错误信息 |
onScaleChanged | WebView发生改变 |
shouldOverrideUrlLoading | 控制新的连接在当前WebView中打开 |
例:检测是否能按下前进和后退键(前进canGoForward)
if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){
//返回前一个页面
mWebView.goBack();
return true;
}
WebChromeClient
辅助WebView处理JavaScript的对话框,网站图标,网站标题,加载进度等。
常用方法
oonCloseWindow | 关闭WebView |
onCreateWindow | 创建WebView |
onJsAlert | 处理JavaScript中的Alert对话框 |
onJsConfirm | 处理JavaScript中的Confirm对话框 |
onJsPrompt | 处理JavaScript中的Prompt对话框 |
onProgressChanged | 加载进度条改变 |
onReceivedIcon | 网页图标更改 |
onReceivedTitle | 网页Title更改 |
onRequestFocus | WebView显示焦点 |
例:更改标题
public void onReceivedTitle(WebView view,String title){
Activity01.this.setTitle(title);
super.onReceivedTitile(view,title);
}
例:
public class Activity01 extends Activity{
private final String DEBUG_TAG = "Activity01";
private Button mButton;
private EditText mEditTEXT;
private WebView mWebView;
public void onCreate(Bundler savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton = (Button)findViewById(R.id.Button01);
mEditText = (EditText)findViewById(R.id.EditText01);
mWebView = (WebView)findViewById(R.id.WebView01);
//设置支持JavaScript脚本
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
//设置可以访问文件
webSettings.setAllowFileAccess(true);
//设置支持缩放
webSettings.setBuiltInZoomControls(true);
//设置webViewClient
mWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrilLoading(WebView view,String uril){
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url){
super.onPangeFinished(view,url);
}
public void onPageStarted(WebView view,String url,Bitmap favicon){
super.onPageStarted(view,url,favicon);
}
});
//设置WebChromeClient
mWebView.setWebChromeClient(new WebChromeClient(){
//处理alert
public boolean onJsAlert(WebView view,String url,String message,final JsResult result){
//构建一个Builder来显示来自网页中的对话框
Builder builder = new Builder(Activity01.this);
builder.setTitle("提示对话框");
builder.setMessage(message);
builder.setPositivieButton(android.R.string.ok,new AlertDialog.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
//点击确定后继续执行网页中的操作
result.confirm();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
};
//处理Confirm
public boolean onJsConfirm(WebView view,String url,String message,final JsResult result){
Builder builder = new Builder(Activity01.this);
builder.setTitle("带选择的对话框");
builder.setMessage(message);
builder.setPositivieButton(android.R.string.ok,new AlertDialog.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
result.confirm();
}
});
builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
result.cancel();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
};
//处理prompt
public boolean onJsPrompt(WebView view,String url,String message,String defaultValue,final JsPromptResult result){
//自定义一个带输入对话框由TextView和EditText构成
final LayoutInflater factory = LayoutInflater.from(Activity01.this);
final View dialogview = factory.inflate(R.layout.prom_dialog,null);
//设置TextView对应网页中的提示信息
((TextView)dialogview.findViewById(R.id.EditText_PROM).setText(defaultValue);
Builder builder = new Builder(Activity01.this);
builder.setTitle("带输入的对话框");
builder.setView(dialogview);
builder.setPositiveButton(android.R.string.ok,new AlerDialog.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
//点击确定后,取得输入值,传给网页处理
String value = ((EditText)dialogview.findViewById(R.id.EditText_PROM).getText().toString();
result.confirm(value);
}
});
builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
result.cancel();
}
});
builder.setCancelListener(android.R.string.cancel,new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
result.cancel();
}
});
builder.show();
retrun true;
};
//设置网页加载的进度条
public void onProgressChanged(WebView view,int newProgress){
Activity01.this.getWindow().setFeatureInt(Window.FEATURE_PROGERSS,newProgress*100);
super.onProgressChanged(View,String title){
Activity01.this.setTitle(title);
super.onReceivedTitle(view,title);
}
pulbic void onReceivedTitle(WebView view,String title){
Activity01.this.setTitle(title);
super.onReceivedTitle(view,title);
}
});
//设置按钮事件监听
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
try{
//取得编辑框的内容
String url = mEditText.getText().toString();
//判断是否输入的为地址
if(URLUtil.isNetworkUril(url)){
//装载地址
mWebView.loadUrl(url);
}else{
mEditText.setText("输入的网址错误,请重新输入!");
}
}catch(Exception e){
Log.e(DEBUG_TAG,e.toString());
}
}
});
}
public void boolean onKeyDown(int keyCode,KeyEvent event){
//后退键,返回上一页
if((keyCode == KEYEvent.KEYCODE_BACK) && mWebView.canGoBack()({
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode,Event);
}
}
例:从Android中调用个人资料,用JavaScript显示
public class Activity01 extends Activity{
private WebView mWebView;
private PersonalData mPersonalData;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPersonalData = new PersonalData();
mWebView = (WebView)this.findViewById(R.id.WebView01);
//设置支持JavaScript
mWebView.getSetting().setJavaScriptEnabled(true);
//把本类的一个实例添加到JavaScript的全局对象window中
mWebView.addJavascriptInterface(this,"PersonalData");
//加载页面
mWebView.loadUrl("file:///android_assest/PersionalData.html");
}
//在JavaScript中调用得到PersonalData对象
public PersonalData getPersonalData(){
reuturn mPersonalData;
}
//JavaScript中调用得到PersonalData对象
public PersonalData getPersonalData(){
return mPersonalData;
}
//Javascript中调用显示的资料
class PersonalData{
String mID;
String mName;
String mAge;
String mBlog;
public PersonalData(){
this.mID="12345567";
this.mName="Android";
this.mAge="100";
this.mBlog="http://eminem.csg.com"
}
public String getID(){
return mID;
}
public String getName(){
return mName;
}
public String getAge(){
return mAge;
}
public String getBlog(){
return mBlog;
}
}
}
assets\test.js javascript访问android应用代码
window.onload = function(){
//取得java对象
var personaldata = window.PersonalData.getPersonalData();
if(personaldata){
var Personaldata = document.getElementById_x("Personldata");
pnode = document.createElement_x("p");
//通过java对象访问数据
tnode = document.createTextNode("ID:"+personaldata.getId());
pnode.appendChild(tnode);
Personaldata.appendChild(pnode);
pnode = document.createElement_x("p");
tnode = document.createTextNode("Name:"+personaldata.getName());
pnode.appendChild(tnode);
Personaldata.appendChild(pnode);
pnode = document.createElement_x("p");
tnode = document.createTextNode("Age:"+personaldata.getAge());
pnode.appendChild(tnode);
Personaldata.appendChild(pnode);
pnode = document.createElement_x("p");
tnode = document.createTextNode("Blog:"+personaldata.getBlog());
pnode.appendChild(tnode);
Personaldata.appendChild(pnode);
pnode = document.createElement_x("p");
}
}
【注】在Android中调用javascript方法:WebView.loadUrl("javascript:方法名()");