webview使用中遇到的坑

1. 硬件加速问题

需要开启硬件加速,在AndroidManifest.xml中进行设置。

否则会出现滚动效率低下,无法播放视频等问题。缺陷:占用内存大。

android:hardwareAccelerated=“true” 针对activity


2. 与js交互的问题

需要在页面load(url)之前,就把java对象注入页面。否则脚本执行时,java对象会找不到。


3. onPause的问题

webview在资源低下的情况下有可能自己进入onPause状态,此时页面会空白一片,如果不点击页面或者重新渲染,将没有画面出现(此问题在开启硬件加速后非常明显)。因此有必要对页面手动进行onResume处理。 


4.onCreateWindow的问题

如何在onCreateWindow事件触发的时机取得url?使用hack的方法:

	@Override
	public boolean onCreateWindow(WebView view, boolean isDialog,
								  boolean isUserGesture, Message resultMsg) {
		// 当前窗口数量已经达到上限,不能再开新窗口进行处理了
		if (TabViewManager.getInstance().getSize() == TabViewManager.MAX_TAB_SIZE) {
			WebView webview = new WebView(view.getContext());
			webview.setWebViewClient(new WebViewClient() {
				@Override
				public boolean shouldOverrideUrlLoading(WebView view, String url) {
					TabViewManager.getInstance().getCurrentTabView().loadUrl(url, NavigateSource.NORMAL);
					return true;
				}
			});

			setWebViewTransport(webview, resultMsg);
			return true;
		}

		// 页面开启新窗口时调用
		WebView webview = (WebView) TabViewManager.getInstance().addTabView(false).getContentView().getWebView().getView();
		setWebViewTransport(webview, resultMsg);
		return true;

	}



5. 请求地理位置信息

在WebViewChromeClient中的onGeolocationPermission方法实现即可


6. HttpAuth,比如路由器填写用户名密码,需要验证的页面

需要在WebViewClient中实现onReceivedHttpAuthRequest方法

	@Override
	public void onReceivedHttpAuthRequest(WebView view,
										  final HttpAuthHandler handler, String host, String realm) {
		// TODO Auto-generated method stub
		final CommonDialog dialog = new CommonDialog(view.getContext());
		String title = view.getContext().getString(R.string.auth_request_login);
		dialog.setTitle(title + host);
		dialog.setCenterView(R.layout.dialog_http_auth_request);
		dialog.setBtnOkListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				dialog.dismiss();
				EditText username = (EditText) dialog.findViewById(R.id.username);
				EditText password = (EditText) dialog.findViewById(R.id.password);
				handler.proceed(username.getText().toString(), password.getText().toString());
			}
		});

		dialog.setBtnCancelListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		dialog.show();

	}



7. 广告拦截

需要实现WebViewClient的shouldInterceptRequest方法

注意:该方法不工作在主线程。因此需要对ui处理的,要抛到主线程去做

@Override
	public WebResourceResponse shouldInterceptRequest(WebView webView, String url) {
		WebResourceResponse wr = null;
		if (ConfigManager.getInstance().isAdBlock() && mService != null) {
			IAdBlockService adBlockService = mService.getAdBlockService();
			String mainUrl = mUrl; // webView.getUrl();
			if (mainUrl == null) {
				mainUrl = url;
			}
			SimpleLog.d(TAG, "shouldInterceptRequest() " + "mainUrl:" + mainUrl + " url:" + url);
			try {
				if (adBlockService != null && adBlockService.isBlockSync(url, mainUrl)) {
					SimpleLog.d(TAG, "isBlocked!");
					try {
						wr = new WebResourceResponse("", "", null);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return wr;
	}



 
 
 
 

对于API21以上的客户端可以采用更好的方法。因为API21的shouldInterceptRequest方法提供了更多参数,比如页面的header信息等。


猜你喜欢

转载自blog.csdn.net/dpk1229/article/details/48731513