浅谈WebView的使用 安卓webview的使用

WebView是Android中一个非常实用的组件,它和Safai、Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面。使用WebView开发软件有一下几个优点:

1.可以打开远程URL页面,也可以加载本地HTML数据;

2.可以无缝的在java和javascript之间进行交互操作;

3.高度的定制性,可根据开发者的需要进行多样性定制。

下面就通过例子来介绍一下WebView的使用方法。

我们先建一个webview项目,项目结构如左图:

  

在这个项目中,我们会先进入MainActivity这个导航界面(上边右图),通过点击不同按钮转向不同的Activity,下面分别简单介绍一下这几个Activity的所要演示的功能:

LoadActivity:主要演示加载网络页面和WebView的一些基本设置;

CaptureActivity:主要演示WebView的截图的功能;

FileActivity:主要演示访问本地文件的功能;

JSActivity:主要演示WebView对JS的支持以及JS和Java之间的互相调用;

接下来,我们会逐一分析各个Activity的相关信息:

LoadActivity:

与之对应的布局文件为load.xml,演示效果如下:

  

我们在文本框中输入URL,然后点击“load”按钮,然后由WebView加载相应的页面,在加载过程中,根据加载进度更新窗口的进度条。由于布局相对简单,我们主要来看一下LoadActivity.java的代码:

[java] view plaincopyprint?

packagecom.scott.webview;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.view.KeyEvent;

importandroid.view.View;

importandroid.view.Window;

importandroid.webkit.WebChromeClient;

importandroid.webkit.WebSettings;

importandroid.webkit.WebView;

importandroid.webkit.WebViewClient;

importandroid.widget.Button;

importandroid.widget.EditText;

publicclassLoadActivityextendsActivity{

privateWebViewwebView;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

//设置窗口风格为进度条

getWindow().requestFeature(Window.FEATURE_PROGRESS);

setContentView(R.layout.load);

webView=(WebView)findViewById(R.id.webView);

WebSettingssettings=webView.getSettings();

settings.setSupportZoom(true);//支持缩放

settings.setBuiltInZoomControls(true);//启用内置缩放装置

settings.setJavaScriptEnabled(true);//启用JS脚本

webView.setWebViewClient(newWebViewClient(){

//当点击链接时,希望覆盖而不是打开新窗口

@Override

publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){

view.loadUrl(url);//加载新的url

returntrue;//返回true,代表事件已处理,事件流到此终止

}

});

//点击后退按钮,让WebView后退一页(也可以覆写Activity的onKeyDown方法)

webView.setOnKeyListener(newView.OnKeyListener(){

@Override

publicbooleanonKey(Viewv,intkeyCode,KeyEventevent){

if(event.getAction()==KeyEvent.ACTION_DOWN){

if(keyCode==KeyEvent.KEYCODE_BACK&&webView.canGoBack()){

webView.goBack();//后退

returntrue;//已处理

}

}

returnfalse;

}

});

webView.setWebChromeClient(newWebChromeClient(){

//当WebView进度改变时更新窗口进度

@Override

publicvoidonProgressChanged(WebViewview,intnewProgress){

//Activity的进度范围在0到10000之间,所以这里要乘以100

LoadActivity.this.setProgress(newProgress*100);

}

});

finalEditTexturl=(EditText)findViewById(R.id.url);

ButtonloadURL=(Button)findViewById(R.id.loadURL);

loadURL.setOnClickListener(newView.OnClickListener(){

@Override

publicvoidonClick(Viewv){

webView.loadUrl(url.getText().toString());//加载url

webView.requestFocus();//获取焦点

}

});

}

}

可以看到,我们使用loadUrl方法加载一个url页面,然后重写WebChromeClient的onProgressChanged方法更新进度条。loadUrl方法除了能加载远程页面,还能加载本地的文件:

[java] view plaincopyprint?

//加载assets中的html文件

webView.loadUrl("file:///android_asset/index.html");

//加载sdcard中的html文件

webView.loadUrl("file:///mnt/sdcard/index.html");

这些都会在后边的示例中使用到。

CaptureActivity:

与之对应的布局文件为capture.xml,也比较简单,它的演示效果如下:

  

记得在AndroidManifest.xml中加入对sdcard的写权限:

[xhtml] view plaincopyprint?

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

截图成功后,在/mnt/sdcard目录下会生成一个当前网页的截图,如图:



我们导出一下,看看是不是当前的网页界面:



整个过程操作已经完成了,让我们来看一下CaptureActivity.java的代码:

[java] view plaincopyprint?

packagecom.scott.webview;

importjava.io.FileOutputStream;

importandroid.app.Activity;

importandroid.graphics.Bitmap;

importandroid.graphics.Canvas;

importandroid.graphics.Picture;

importandroid.os.Bundle;

importandroid.util.Log;

importandroid.view.View;

importandroid.webkit.WebView;

importandroid.widget.Button;

importandroid.widget.Toast;

publicclassCaptureActivityextendsActivity{

privatestaticfinalStringTAG="CAPTURE";

privateWebViewwebView;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.capture);

webView=(WebView)findViewById(R.id.webView);

webView.loadUrl("http://www.baidu.com");

Buttoncapture=(Button)findViewById(R.id.capture);

capture.setOnClickListener(newView.OnClickListener(){

@Override

publicvoidonClick(Viewv){

//取得android.graphics.Picture实例

Picturepicture=webView.capturePicture();

intwidth=picture.getWidth();

intheight=picture.getHeight();

if(width>0&&height>0){

//创建指定高宽的Bitmap对象

Bitmapbitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);

//创建Canvas,并以bitmap为绘制目标

Canvascanvas=newCanvas(bitmap);

//将WebView影像绘制在Canvas上

picture.draw(canvas);

try{

StringfileName="/sdcard/webview_capture.jpg";

FileOutputStreamfos=newFileOutputStream(fileName);

//压缩bitmap到输出流中

bitmap.compress(Bitmap.CompressFormat.PNG,90,fos);

fos.close();

Toast.makeText(CaptureActivity.this,"CAPTURESUCCESS",Toast.LENGTH_LONG).show();

}catch(Exceptione){

Log.e(TAG,e.getMessage());

}

}

}

});

}

}

FileActivity:

这个界面没有布局文件,在代码中完成,它将演示如何加载一段html代码,并应用刚才生成的网页截图,效果如下图:



在这个过程中,我们加载了截图,并给图加上了红色的边框,CaptureActivity.java代码如下:

[java] view plaincopyprint?

packagecom.scott.webview;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.webkit.WebView;

publicclassFileActivityextendsActivity{

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

WebViewwebView=newWebView(this);

webView.getSettings().setAllowFileAccess(true);//默认就是启用的,这里只是强调一下

StringbaseURL="file:///mnt/sdcard/";//根URL

Stringhtml="<html><body>"

+"<h3>imagefromsdcard:<h3><br/>"

+"<imgsrc='webview_capture.jpg'style='border:2pxsolid#FF0000;'/>"

+"</body></html>";

//加载相对于根URL下的数据,historyUrl设为null即可

webView.loadDataWithBaseURL(baseURL,html,"text/html","utf-8",null);

setContentView(webView);

}

}

如果将html文本保存成.html文件,放于/mnt/sdcard目录下,然后用以下方式加载也能达到相同的效果:

[java] view plaincopyprint?

webView.loadUrl("file:///mnt/sdcard/index.html");

接下来是最后一个示例:JSActivity,也是最精彩的示例,演示如何在JS和Java之间通信,我们来看一下演示过程,如图:

  

  

然后谈谈我们的执行过程,我们需要在Java代码中设置WebView的一些事件的响应,比如alert、confirm以及prompt这些JS事件,让它们按照我们的要求呈现给用户,然后我们需要定义一个Java和JS之间的接口对象,当我们加载完一个html文档后,根据这个对象的接口名称就可以在文档的JS代码中轻松的调用这个接口对象的方法,执行Java代码,我们也可以在Java端执行html文档中的JS代码。下面我们将通过代码来证实这一过程:

JSActivity.java代码如下:

[java] view plaincopyprint?

packagecom.scott.webview;

importjava.util.ArrayList;

importjava.util.List;

importandroid.app.Activity;

importandroid.app.AlertDialog;

importandroid.content.DialogInterface;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.Log;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.view.Window;

importandroid.webkit.JsPromptResult;

importandroid.webkit.JsResult;

importandroid.webkit.WebChromeClient;

importandroid.webkit.WebView;

importandroid.widget.EditText;

importandroid.widget.Toast;

publicclassJSActivityextendsActivity{

privatestaticfinalStringTAG="JSActivity";

privateWebViewwebView;

privateHandlerhandler=newHandler(){

publicvoidhandleMessage(android.os.Messagemsg){

intindex=msg.arg1;

JSActivity.this.setProgress(index*1000);

};

};

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

getWindow().requestFeature(Window.FEATURE_PROGRESS);

webView=newWebView(this);

webView.getSettings().setJavaScriptEnabled(true);

webView.addJavascriptInterface(newObject(){

@SuppressWarnings("unused")

publicList<String>getList(){

List<String>list=newArrayList<String>();

for(inti=0;i<=10;i++){

try{

Thread.sleep(200);

}catch(InterruptedExceptione){

Log.e(TAG,"error:"+e.getMessage());

}

list.add("currentindexis:"+i);

//不能在此直接调用Activity.setProgress,否则会报以下错误

//Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.

Messagemsg=handler.obtainMessage();

msg.arg1=i;

handler.sendMessage(msg);

}

success();

returnlist;

}

publicvoidsuccess(){

//由Java代码调用JS函数

webView.loadUrl("javascript:success('congratulations')");

}

},"bridge");

webView.setWebChromeClient(newWebChromeClient(){

@Override

publicbooleanonJsAlert(WebViewview,Stringurl,Stringmessage,finalJsResultresult){

newAlertDialog.Builder(JSActivity.this)

.setTitle("alert")

.setMessage(message)

.setPositiveButton("YES",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

//处理结果为确定状态同时唤醒WebCore线程

result.confirm();

}

}).create().show();

returntrue;//已处理

}

@Override

publicbooleanonJsConfirm(WebViewview,Stringurl,Stringmessage,finalJsResultresult){

newAlertDialog.Builder(JSActivity.this)

.setTitle("confirm")

.setMessage(message)

.setPositiveButton("YES",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

Toast.makeText(JSActivity.this,"youclickedyes",0).show();

result.confirm();

}

})

.setNegativeButton("NO",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

//处理结果为取消状态同时唤醒WebCore线程

result.cancel();

}

}).create().show();

returntrue;

}

@Override

publicbooleanonJsPrompt(WebViewview,Stringurl,Stringmessage,StringdefaultValue,

finalJsPromptResultresult){

LayoutInflaterinflater=getLayoutInflater();

Viewprompt=inflater.inflate(R.layout.prompt,null);

finalEditTexttext=(EditText)prompt.findViewById(R.id.prompt_input);

text.setHint(defaultValue);

newAlertDialog.Builder(JSActivity.this)

.setTitle("prompt")

.setView(prompt)

.setPositiveButton("YES",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

//记录结果

result.confirm(text.getText().toString());

}

})

.setNegativeButton("NO",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

result.cancel();

}

}).create().show();

returntrue;

}

});

//加载assets中的html文件

webView.loadUrl("file:///android_asset/index.html");

setContentView(webView);

}

}

需要注意的是,在重写onJsAlert、onJsConfirm、onJsPrompt这几个方法中,不要忘了用JsResult.confirm()或JsResult.cancel()处理结果,否则页面就不能再响应接下的事件了,关于这一点,我们可以看一下JsResult的代码:

[c-sharp] view plaincopyprint?

/**

*Handleaconfirmationresponsefromtheuser.

*/

publicfinalvoidconfirm(){

mResult=true;

wakeUp();

}

/**

*Handletheresultiftheusercancelledthedialog.

*/

publicfinalvoidcancel(){

mResult=false;

wakeUp();

}

可以看到confirm和cancel方法都涉及到了一个wakeUp方法,这个方法主要作用是唤醒WebCore线程,定义如下:

[c-sharp] view plaincopyprint?

/*WakeuptheWebCorethread.*/

protectedfinalvoidwakeUp(){

if(mReady){

synchronized(mProxy){

mProxy.notify();

}

}else{

mTriedToNotifyBeforeReady=true;

}

}

所以朋友们如果要重写这几个方法时要切记处理JsResult这个对象实例。

我们在处理onJsPrompt时,使用了自定义的界面,加载的是/res/layout/prompt.xml,定义如下:

[xhtml] view plaincopyprint?

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<EditText

android:id="@+id/prompt_input"
浅谈WebView的使用 安卓webview的使用

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>

</LinearLayout>

在JSActivity.java代码中,我们注意到WebView组件加载了assets中的index.html,它包含与Java交互的JS代码,如下:

[xhtml] view plaincopyprint?

<html>

<head>

<scripttype="text/javascript">

functiondoAlert(){

alert("hello!");

}

functiondoConfirm(){

confirm("areyousure?");

}

functiondoPrompt(){

varval=prompt("what'syourname?");

if(val){

alert("yournameis:"+val);

}

}

functiongetList(){

//使用java和javascript的接口bridge的方法获取集合

varlist=window.bridge.getList();

varresult=document.getElementById("result");

for(vari=0;i<list.size();i++){

vardiv=document.createElement("div");

div.innerHTML=list.get(i).toString();

result.appendChild(div);

}

}

functionsuccess(msg){

alert(msg);

}

</script>

</head>

<bodybackground="black">

<inputtype="button"value="alert"onclick="doAlert()"/><br/>

<inputtype="button"value="confirm"onclick="doConfirm()"/><br/>

<inputtype="button"value="prompt"onclick="doPrompt()"/><br/>

<inputtype="button"value="getList"onclick="getList()"/><br/>

<divid="result"></div>

</body>

</html>

WebView的优点还不止这些,希望在今后的时间里,再和大家分享WebView的相关技术,也希望这篇文章能够对初识WebView的朋友们带来帮助。

  

爱华网本文地址 » http://www.aihuau.com/a/25101012/131997.html

更多阅读

转载 浅谈中医的“不传之秘” 转载 寻龙点穴秘笈

原文地址:浅谈中医的“不传之秘”作者:深圳梧桐山中医学堂浅谈中医的“不传之秘”导读中医不传之秘,不尽在药量,而在中医大家辩证精准,用药如用兵,老辣不拘一格,方显药量精奇,所谓“胆欲大而心欲细”,药量峻猛称奇非为“秘传”,琴心剑胆绝技

浅谈方大特钢的价值2015年3月22日 浅谈教师的人生价值观

方大特钢14年年报及分红出来后,才让我注意到方大特钢,就对其做了一些功课,现在谈谈我的意见,仅供参考。第一,方大特钢,有2个上市公司的第一,1,公司总裁钟崇武年薪2038万,号称打工皇帝,近3年来一直是上市公司老总年薪最高的。(1517,1974 2038)2,1

浅谈WebView的使用 安卓webview的使用

WebView是Android中一个非常实用的组件,它和Safai、Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面。使用WebView开发软件有一下几个优点:1.可以打开远程URL页面,也可以加载本地HTML数据;2.可以

浅谈调研文章写作的体会 浅谈我的写作经验

尊敬的各位领导、同事们您好:非常感谢研究室给我一次和大家进行学习和交流的机会。今天我结合自己曾参与写过的《涉本区农工商公司案件的调查与思考》谈几点自己写调研文章的体会,以和大家共勉。俗话说“文章自古无凭据,唯有朱衣暗点头

浅谈土家族的婚俗过程 土家族吊脚楼

浅谈土家族的婚俗过程一. 内容摘要:土家族是一个非常古老的民族, “华兹卡”是土家族的自称,意为本地人,据2000年我国人口普查统计,全国土家族共570.4万人,其主要分布在铜仁地区,德江县,沿河县等周边地区;关于记载土家族的文献很多,但是保存

声明:《浅谈WebView的使用 安卓webview的使用》为网友少年的第一个梦分享!如侵犯到您的合法权益请联系我们删除