飞鸟

学习笔记

webview

参考

        http://developer.android.com/guide/webapps/webview.html

基础

        webview就是一个组件,可以和textview一样使用。可以调用loadUrl("http://www.baidu.com")进行加载指定了url的网页。

        当加载一个界面后,点击其中的链接,会调用系统的浏览器进行访问。如果想要用自己的webview访问,可以设置webview.setWebViewClient(new WebViewClient());即可。

        WebViewClient中有shouldOverrideUrlLoading():返回true,就代表由应用的代码处理该url,webview不处理;返回false,就代表用webview本身进行访问(WebViewClient类中的shouldOverrideUrlLoading默认的是返回false)。还有onPageStarted(),onPageFinished()方法,因此可以在刚开始加载界面的时候弹出一个进度条,而界面加载完成之后进度条消失。

        所以可以根据url的不同,来选择用webview访问还是浏览器进行访问。调用浏览器的Intent:

        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(intent);
        webview还可以直接加载html数据,如
mWebView.loadData("<html><body>"+str+"</body></html>", "text/html", "utf-8");

常用功能

post请求网页

        使用postUrl()进行加载即可。第一个参数为请求的链接,第二个参数为post的请求体。如下:
        Map<String, String> pairs = mWebBean.getFormPairs();
        if (pairs != null) {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : pairs.entrySet()) {
                sb.append(entry.getKey());
                sb.append("=");
                sb.append(entry.getValue());
                sb.append("&");
            }//拼装请求参数
            byte[] post = EncodingUtils.getBytes(sb.toString(), "BASE64");//将请求参数以base64的方式进行加密
            webView.postUrl(mWebBean.getUrl(), post);
            return true;
        }

刷新

        webview的刷新很简单,调用WebView.reload()即可。

加载https

        在有些手机中,webview加载https会加载不出来。解决办法为:重写WebViewClient#onReceivedSslError,并使用handler.proceed()。如下:
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed();//handler.cancel()
            }
        此种方法是认证所有的https请求。

加载错误界面

        用webview访问时,如果界面加载失败,webview会加载一个系统默认的错误界面。可以通过如下方法进行修改:
		mWebView.setWebViewClient(new WebViewClient(){
			@Override
			public void onReceivedError(WebView view, int errorCode,
					String description, String failingUrl) {
				//该方法中加载本地的错误界面。如assets目录下的error.html
				view.loadUrl("file:///android_asset/error.html");
				super.onReceivedError(view, errorCode, description, failingUrl);
			}
		});

返回键

        正确的处理应该是:如果是网页,就应该返回到上一个网页,否则就直接退出程序。代码

public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK && view != null && view.canGoBack()){//如果仍在网页中,就退回上一个网页
			view.goBack();
			return true;
		}else{//退到最先的一个网页,再按退出就退出程序
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}
        canGoBack():当退到开始进入的网页时就返回false,从而执行下面的finish()方法。

        然而,上面处理方法有一个弊端:每一次返回上一个界面的时候,就会自动刷新(好像是底层的原因,没有办法更改)。如果不想要自动刷新,就不能用上面的方法处理返回键。为了达到不刷新的效果,只能是一个界面就用一个activity,同时不需要重写onKeyDown()方法。,这样返回的时候就是返回到上一个activity了,还是保留了原来的样子。实现方法是:

wv.setWebViewClient(new WebViewClient(){
			public boolean shouldOverrideUrlLoading(WebView view, String url) {//重新加载的时候开启新的activity,为了返回键(保证返回时内容还是原来的样子)
				Intent intent = new Intent(StudentWebActivity.this,StudentWebActivity.class);
				intent.putExtra("studentId", stuId);
				intent.putExtra("url", url);
				startActivity(intent);
				return true;//要返回true。
			}
		});

下载

        在webview中直接进行下载。代码如下:

		mWebView.setDownloadListener(new DownloadListener() {
			@Override
			public void onDownloadStart(String url, String userAgent,
					String contentDisposition, String mimetype, long contentLength) {
				//url为所需要下载的资源的链接。下面是调用系统的浏览器进行下载
				Uri uri = Uri.parse(url);
				Intent i = new Intent(Intent.ACTION_VIEW, uri);
				startActivity(i);
			}
		});

与JS互调

js调用android

        为了方便,可以写一个html,放在assets中,loadUrl("file:///android_asset/demo.html");即可。

html代码示例:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>demo.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  <script type="text/javascript">
  	function demo(params){
  		window.android.toast(params);
  	}
  </script>
  <body>
    	<input type="button" value="提交" onclick="demo('a');" />
  </body>
</html>
在android端:
		view.addJavascriptInterface(new Object(){//网页调用android代码
			public void toast(String s){
				Toast.makeText(ShowTable.this, s, Toast.LENGTH_SHORT).show();
			}
		}, "android");

        在js中,只需要通过window.xxx就可以调用到android中的代码。其中xxx是addJavaScriptInterface中的第二个参数。

android调用js

       webview.loadUrl("javascript:getNode3()");//getNode3()就是js中的方法

常见问题

显示加载进度

        用webview加载界面时,可以在界面上方显示一个加载进度,主要通过WebChromeClient.onProgressChanged()进行更新。如下:
		mWv.setWebChromeClient(new WebChromeClient() {
			//更新加载进度
			public void onProgressChanged(WebView view, int newProgress) {
				mPb.setProgress(newProgress);
			}
			//当加载到界面的title时
			public void onReceivedTitle(WebView view, String title) {
				mTv.setText(title);
			}
		});

对话框及activity关闭后弹框处理

        网页中经常会弹出一些dialog,默认时系统会使用自己的dialog,也可重写相应的方法弹出自定义的dialog。要重写的方法WebChromeClient#onJsAlert(),WebChromeClient#onJsConfirm()与WebChromeClient#onJsPrompt()。这几个方法主要区别在于js弹框时使用的方法,如js使用alert()时,对应的是onJsAlert()。
        这些方法返回true时,代表程序自己处理了js中的弹框,webview不会再进行处理。返回false时webview还会再进行处理。这点与shouldOverrideUrlLoading()方法的返回值类似。
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                if(view != null && view.isShown() && view.getContext() != null){
                    return super.onJsAlert(view,url,message,result);
                }
                result.confirm();
                return true;
            }
        当webview所处的activity关闭后,js仍旧会弹出dialog,此时应用就会崩溃。因此在弹出之前需要进行if判断。并且该activity关闭后,不应该再弹框,所以onJsAlert()应该返回true。
        虽说自己的应用不会弹出dialog,但实际上网页中仍旧会有一个dialog存在,因此再次进入该界面时,就会加载不出来。所以需要在onJsAlert()中调用result.confirm(),保证网页的dialog消失。这样下次进来时就会再次加载出界面。

乱码

        使用loadData()加载html时,有时候会出现乱码。可以用loadDataWithBaseURL()代替loadData();如:

wv.loadDataWithBaseURL (null, html, "text/html", "utf-8",null);
如果不行就加上:
		WebSettings settings = wv.getSettings();
		settings.setDefaultTextEncodingName("utf-8");

图片过大

        加载的数据中如果有图片的话,有可能会超过屏幕,从而需要横向滑动才行。可以进行相应的缩小:

WebSettings settings = wv.getSettings();
		settings.setUseWideViewPort(true); 
        settings.setLoadWithOverviewMode(true); 
这样的缩小会将文字和图片一起缩小,可能使得文字看不见。可以采用下面方法 :
	WebSettings settings = wv.getSettings();
	settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
	settings.setLoadWithOverviewMode(true);

示例

public class ShowTable extends Activity {

	private WebView view;
	private Button btn;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		view = (WebView) findViewById(R.id.tv_left);
		btn = (Button) findViewById(R.id.btn);
		
		btn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				view.loadUrl("javascript:display_alert('sqgefergklp')");//调用js中的方法,参数需要用‘’括起来
			}
		});
		
		view.getSettings().setJavaScriptEnabled(true);
		view.loadUrl("file:///android_asset/alert.html");//加载js
		
		view.setWebChromeClient(new WebChromeClient(){
			@Override
			public boolean onJsAlert(WebView view, String url, String message,
					JsResult result) {//js中用alert()时
				final JsResult res = result;
				AlertDialog.Builder builder = new AlertDialog.Builder(ShowTable.this);
				builder.setTitle(null);
				builder.setMessage(message);
				builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						res.confirm();
					}
				});
				builder.setCancelable(false);
				builder.create();
				builder.show();
				return true;
			}
			@Override
			public boolean onJsConfirm(WebView view, String url,
					String message, JsResult result) {//js中用confirm()时
				final JsResult res = result;
				AlertDialog.Builder builder = new AlertDialog.Builder(ShowTable.this);
				builder.setTitle(null);
				builder.setMessage(message);
				builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						res.confirm();
					}
				});
				builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						res.cancel();
					}
				});
				builder.setCancelable(false);
				builder.create();
				builder.show();
				return true;
			}
			@Override
			public boolean onJsPrompt(WebView view, String url, String message,
					String defaultValue,final JsPromptResult result) {//注意最后一个参数的类型,不是JsResult,而是JsPromptResult
				//js中有prompt时。此处,自己定义一个显示的对话框,用于代替网页中本身显示的prompt对话框
				View view2 = View.inflate(ShowTable.this, R.layout.test, null);
				final EditText et = (EditText) view2.findViewById(R.id.et_text);
				et.setText(defaultValue);
				TextView tv = (TextView) view2.findViewById(R.id.tv);
				tv.setText(message);
				AlertDialog.Builder builder = new AlertDialog.Builder(ShowTable.this);
				builder.setTitle(null);
				builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						String string = et.getText().toString();
						result.confirm(string);
					}
				});
				builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						result.cancel();
					}
				});
				builder.setView(view2);
				builder.setCancelable(false);
				builder.create();
				builder.show();
				return true;
			}
		});
		view.setWebViewClient(new WebViewClient(){
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				return false;
			}
		});
		view.addJavascriptInterface(new Object(){//网页调用android代码
			public void toast(String s){
				Toast.makeText(ShowTable.this, s, Toast.LENGTH_SHORT).show();
			}
		}, "android");
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK && view != null && view.canGoBack()){//如果仍在网页中,就退回上一个网页
			view.goBack();
			return true;
		}else{//退到最先的一个网页,再按退出就退出程序
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}







            
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010410408/article/details/17098853
个人分类: 常用类
博主设置当前文章不允许评论。

Android webview flash

2011年01月11日 577KB 下载

WebView的使用Demo

2014年06月19日 1.26MB 下载

webView的应用

2013年02月27日 65KB 下载

android webview richeditor

2015年09月10日 1.49MB 下载

android webview

2013年10月19日 40KB 下载

Android WebView实现视频全屏

2014年08月25日 84KB 下载

Android WebView实例

2013年04月29日 913KB 下载

Android与WebView交互

2016年10月13日 24.51MB 下载

WebView控件基本使用 Android

2011年08月31日 22KB 下载

webview重载说明

2015年07月22日 6KB 下载

没有更多推荐了,返回首页

不良信息举报

webview

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭