Android如何设计一个H5容器

Android如何设计一个H5容器,第1张

Android如何设计一个H5容器

APP端使用WebView的场景主要是加载H5页面、富文本展示和编辑、图表库(echart)等。当业务对APP动态化有相应需求时,H5作为一个老牌跨平台技术,是最常用的动态化技术之一。本文对WebView的技术需求和使用场景进行了整理,其中大部分是本人工作中遇到过的,部分是在查阅资料过程中发现的,希望对今后的开发有所帮助。

先来谈一谈H5容器的设计目标:

  • 良好的js与原生通讯支持:支持自定义通讯接口;
  • 性能尽可能好,加载速度尽量快:H5本地模版和webview缓存;
  • 可配置,扩展性好:默认配置合理,满足多数场景需求,同时支持丰富的自定义配置;
  • 用户交互的全面支持:状态展示(loading/error/success)、权限申请、文件选择、大图查看、视频全屏、内容复制粘贴、输入框键盘等等;

本文将围绕这些目标展开,结合WebView的基本用法介绍,力求尽量全面地了解WebView的使用。

WebView基本用法 WebView

查看android api 27及之前版本的WebView源码,发现出于线程安全的考虑,WebView的公开接口内部都做了android.webkit.WebView#checkThread处理,以确保所有相关接口的调用都在同一个线程中。api 28及之后WebView继承MockView成为傀儡类,虽然无法直接看到内部逻辑,但是有理由相信这个准则还是不变的,所以推荐在调用WebView相关接口时要注意在主线程调用。

生命周期相关接口

初始化:

mWebView = new WebView(getContext());
// 可选:自定义配置
WebSettings webSettings = mWebView.getSettings();
// 可选:自定义WebViewClient
mWebView.setWebViewClient(new WebViewClient(){...});
// 可选:自定义WebChromeClient
mWebView.setWebChromeClient(new WebChromeClient(){...});
// 可选:添加JS回调
mWebView.addJavascriptInterface(new Object(){ @JavascriptInterface...}, namespace);

前台:

    @Override
    public void onResume() {
    	// 继续被中断的 *** 作
        mWebView.onResume();
        super.onResume();
    }

后台:

    @Override
    public void onPause() {
        super.onPause();
        // Pauses any extra processing associated with this WebView and its 
        // associated DOM, plugins, Javascript etc. For example, if this 
        // WebView is taken offscreen, this could be called to reduce 
        // unnecessary CPU or network traffic. When this WebView is again 
        // "active", call onResume(). Note that this differs from pauseTimers(),
        // which affects all WebViews.
        mWebView.onPause();
    }

销毁:

// 必须,防止内存泄漏,参见:https://www.jianshu.com/p/eada9b652d99
((ViewGroup) mWebView.getParent()).removeView(this);
// 可选
mWebView.loadDataWithbaseURL(null, "", "text/html", "utf-8", null);
// 可选,停止JS加载,如果前面已经调用了onPause则这里不用
mWebView.stopLoading();
// 可选,退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
mWebView.getSettings().setJavascriptEnabled(false);
// 可选
mWebView.clearHistory();
mWebView.clearView();
mWebView.removeAllViews();
// 必须,需要在最后调用,此方法调用不能再调用mWebView的任何方法
mWebView.destroy();
加载数据
// 加载指定url,url可以是以下:
// 1. [http_url]:比如http://www.baidu.com
// 2. [assets_url]:比如file:///android_asset/content.html
// 3. [file_url]:本地文件绝对路径
// 4. [js_url]:javascript:getText(),详见原生调用JS
// 5. ["about:blank"]:空页面,用于清空webview内容并释放资源
mWebView.loadUrl("url");
// 加载指定http url,并添加自定义请求头
mWebView.loadUrl("url", Collections.emptyMap());

// 使用post请求加载指定url,bytes为urlencode过的数据,将作为post请求body,
// 如果url非http地址,则等同于loadUrl("url")
mWebView.postUrl("url", bytes);

// 加载HTML文本
// 注意data须经UrlEncoder进行编码,不能出现英文字符:’#’, ‘%’, ‘’ , ‘?’ 这四个字符
mWebView.loadData("data","mimeType","encoding");
// 加载HTML文本,data没有上面的限制,因此使用更多
// String baseUrl:基准URL,不需要可以传null。如果data中的url是相对地址,则就会加上基准url来拼接出完整的地址
// String mimeType:MIME类型,通常是“text/html”
// String encoding:编码方式
// String historyUrl:插入历史记录的值,不需要传Null
mWebView.loadDataWithbaseURL("baseUrl","data","mimeType","encoding","historyUrl");

// 停止加载
mWebView.stopLoading();

// 重新加载当前URL
mWebView.reload();
  • loadData()与loadDataWithbaseURL()
    通过loadUrl()来加载本地页面和在线地址的方式需要很长的加载时间,而这两个方法不是用来加载整个页面文件的,而是用来加载一段代码片。比如可以先通过http将网页HTML数据从服务器下载回来,在通过这两个方法就可以很快把页面加载出来,没有很长的访问网络CDN解析等时间。两者比较推荐使用后者,虽然loadData的历史记录不需要我们自己来实现,但在使用时,加载上后者比前者快一到两倍。另外loadData不能加载图片,而loadDataWithbaseURL是可以加载图片的。
  • loadDataWithbaseURL()
    loadDataWithbaseURL它本身并不会向历史记录中存储数据,要想实现历史记录,需要我们自己来实现;有关历史记录的实现方式是比较复杂的,历史记录是以Key/value的方式存储在一个historyList里的,当前进后退时,会用Key来取出对应的value值来加载进webview中。而Key就是这里的baseUrl,Value就是这里的historyUrl;history所指向的必须是一个页面,并且页面存在于SD卡中或程序中(assets);

想要了解更多webview支持的url类型,参见:android.webkit.URLUtil

页面导航
// 获取当前页面URL
String url = mWebView.getUrl();
// 获取当前初始实际加载的URL,比如重定向后的URL
String originalUrl = mWebView.getOriginalUrl();
boolean b = mWebView.canGoBack();
mWebView.canGoBackOrForward(steps);
boolean b1 = mWebView.canGoForward();
mWebView.goBack();
mWebView.goForward();
mWebView.goBackOrForward(steps);

对于常规的多页H5应用,那么上述webview接口已经可以实现activity对webview页面的管控了,但是目前很多H5应用是单页应用,回退 *** 作需要APP端和H5端协调好接口,比如JS仿照webview的已有接口:canGoBack()和goBack()进行实现,由原生APP端进行调用。

其他接口
// 取消已经选中的webview里的文字,需要搭配View#clearFocus()使用
mWebView.clearMatches();

mWebView.clearFormData();

mWebView.clearHistory();

mWebView.clearSslPreferences();

// 已废弃,情况网页内容,显示空白页
mWebView.clearView();

// 这里比较难理解的可能是realm,它是指服务端配置用户认证配置中的AuthName(Apache httpd http://httpd.apache.org/docs/2.0/howto/auth.html)
mWebView.setHttpAuthUsernamePassword("host","realm","username","password");
String[] usernamePassword = mWebView.getHttpAuthUsernamePassword("host","realm");

SslCertificate certificate = mWebView.getCertificate();
mWebView.setCertificate(certificate);

mWebView.setNetworkAvailable(true);

// 获取html内容宽高
int contentHeight = mWebView.getContentHeight();
int contentWidth = mWebView.getContentWidth();
Tricks 浏览器用户认证
  • setHttpAuthUsernamePassword(“host”,“realm”,“username”,“password”)使用场合
    一个需要用户认证的网址:http://api.test.com/userinfo/vid?=1234
    使用curl访问方式:
curl -u username:password http://api.test.com/userinfo/vid?=1234

使用webview访问:

// 错误,无法访问
// realm不能为空,该参数可以从:
// 1. 到服务器配置>>用户认证配置获取
// 2. 在WebViewClient#onReceivedHttpAuthRequest回调中,也有realm参数
mWebView.setHttpAuthUsernamePassword("api.test.com", "", "username", "password");
mWebView.loadUrl("http://api.test.com/userinfo/vid?=1234");

或使用webview WebViewClient回调:

webview.setWebViewClient(new MyWebViewClient ());

private class MyWebViewClient extends WebViewClient {
    @Override
    public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
    	// 这里正确的做法是d窗对话框让用户输入用户名密码
        // 如果直接调用接口,则必须使用正确的用户名密码,否则webview会一直发送请求
        // 当出现请求错误时,可以尝试使用mWebView.stopLoading()来终止retry行为
        handler.proceed("username", "password");
        
    }
}

或将用户名密码拼接到url进行访问,类似curl:

mWebView.loadUrl("http://username:password@api.test.com/userinfo/vid?=1234");

参考资料:Using WebView setHttpAuthUsernamePassword?

WebSettings API
  • void setSupportZoom(boolean support)

Sets whether the WebView should support zooming using its on-screen zoom controls and gestures. The particular zoom mechanisms that should be used can be set with setBuiltInZoomControls. This setting does not affect zooming performed using the WebView.zoomIn() and WebView.zoomOut() methods. The default is true.

Params:
support – whether the WebView should support zoom

  • void setMediaPlaybackRequiresUserGesture(boolean require)

Sets whether the WebView requires a user gesture to play media. The default is true.

Params:
require – whether the WebView requires a user gesture to play media

  • void setBuiltInZoomControls(boolean enabled)

Sets whether the WebView should use its built-in zoom mechanisms. The built-in zoom mechanisms comprise on-screen zoom controls, which are displayed over the WebView’s content, and the use of a pinch gesture to control zooming. Whether or not these on-screen controls are displayed can be set with setDisplayZoomControls. The default is false.
The built-in mechanisms are the only currently supported zoom mechanisms, so it is recommended that this setting is always enabled.

Params:
enabled – whether the WebView should use its built-in zoom mechanisms

  • void setDisplayZoomControls(boolean enabled)

Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. See setBuiltInZoomControls. The default is true.

Params:
enabled – whether the WebView should display on-screen zoom controls

  • void setAllowFileAccess(boolean allow)

Enables or disables file access within WebView. File access is enabled by default. Note that this enables or disables file system access only. Assets and resources are still accessible using file:///android_asset and file:///android_res.

  • void setAllowContentAccess(boolean allow)

Enables or disables content URL access within WebView. Content URL access allows WebView to load content from a content provider installed in the system. The default is enabled.

  • void setAllowUniversalAccessFromFileURLs(boolean flag)

Sets whether Javascript running in the context of a file scheme URL should be allowed to access content from any origin. This includes access to content from other file scheme URLs. See setAllowFileAccessFromFileURLs. To enable the most restrictive, and therefore secure policy, this setting should be disabled. Note that this setting affects only Javascript access to file scheme resources. Other access to such resources, for example, from image HTML elements, is unaffected. To prevent possible violation of same domain policy on android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH and earlier devices, you should explicitly set this value to false.
The default value is true for API level android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 and below, and false for API level android.os.Build.VERSION_CODES.JELLY_BEAN and above.

Params:
flag – whether Javascript running in the context of a file scheme URL should be allowed to access content from any origin

  • void setLoadsImagesAutomatically(boolean flag)

Sets whether the WebView should load image resources. Note that this method controls loading of all images, including those embedded using the data URI scheme. Use setBlockNetworkImage to control loading only of images specified using network URI schemes. Note that if the value of this setting is changed from false to true, all images resources referenced by content currently displayed by the WebView are loaded automatically. The default is true.

Params:
flag – whether the WebView should load image resources

  • void setBlockNetworkImage(boolean flag)

Sets whether the WebView should not load image resources from the network (resources accessed via http and https URI schemes). Note that this method has no effect unless getLoadsImagesAutomatically returns true. Also note that disabling all network loads using setBlockNetworkLoads will also prevent network images from loading, even if this flag is set to false. When the value of this setting is changed from true to false, network images resources referenced by content currently displayed by the WebView are fetched automatically. The default is false.

Params:
flag – whether the WebView should not load image resources from the network

  • void setBlockNetworkLoads(boolean flag)

Sets whether the WebView should not load resources from the network. Use setBlockNetworkImage to only avoid loading image resources. Note that if the value of this setting is changed from true to false, network resources referenced by content currently displayed by the WebView are not fetched until WebView.reload is called. If the application does not have the android.Manifest.permission.INTERNET permission, attempts to set a value of false will cause a SecurityException to be thrown. The default value is false if the application has the android.Manifest.permission.INTERNET permission, otherwise it is true.

Params:
flag – whether the WebView should not load any resources from the network

  • void setLoadWithOverviewMode(boolean overview)

Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width. This setting is taken into account when the content width is greater than the width of the WebView control, for example, when getUseWideViewPort is enabled. The default is false.

  • void setSaveFormData(boolean save)

Sets whether the WebView should save form data. The default is true.

  • void setTextZoom(int textZoom)

Sets the text zoom of the page in percent. The default is 100.

  • void setAcceptThirdPartycookies(boolean accept)

Sets policy for third party cookies. Developers should access this via cookieManager.setShouldAcceptThirdPartycookies.

  • void setUseWideViewPort(boolean use)

Sets whether the WebView should enable support for the “viewport” HTML meta tag or should use a wide viewport. When the value of the setting is false, the layout width is always set to the width of the WebView control in device-independent (CSS) pixels. When the value is true and the page contains the viewport meta tag, the value of the width specified in the tag is used. If the page does not contain the tag or does not provide a width, then a wide viewport will be used.

Params:
use – whether to enable support for the viewport meta tag

  • void setSupportMultipleWindows(boolean support)

Sets whether the WebView whether supports multiple windows. If set to true, WebChromeClient.onCreateWindow must be implemented by the host application. The default is false.

Params:
support – whether to suport multiple windows

  • void setJavascriptCanOpenWindowsAutomatically(boolean flag)

Tells Javascript to open windows automatically. This applies to the Javascript function window.open(). The default is false.

Params:
flag – true if Javascript can open windows automatically

  • void setLayoutAlgorithm(LayoutAlgorithm l)

Sets the underlying layout algorithm. This will cause a relayout of the WebView. The default is WebSettings.LayoutAlgorithm.NARROW_COLUMNS.

Params:
l – the layout algorithm to use, as a WebSettings.LayoutAlgorithm value

  • void setStandardFontFamily(String font)

Sets the standard font family name. The default is “sans-serif”.

Params:
font – a font family name

  • void setFixedFontFamily(String font)

Sets the fixed font family name. The default is “monospace”.

Params:
font – a font family name

  • void setSansSerifFontFamily(String font)

Sets the sans-serif font family name. The default is “sans-serif”.

Params:
font – a font family name

  • void setSerifFontFamily(String font)
    Sets the serif font family name. The default is “sans-serif”.

Params:
font – a font family name

  • void setCursiveFontFamily(String font)

Sets the cursive font family name. The default is “cursive”.

Params:
font – a font family name

  • void setFantasyFontFamily(String font)

Sets the fantasy font family name. The default is “fantasy”.

Params:
font – a font family name

  • void setMinimumFontSize(int size)

Sets the minimum font size. The default is 8.

Params:
size – a non-negative integer between 1 and 72. Any number outside the specified range will be pinned.

  • void setMinimumLogicalFontSize(int size)

Sets the minimum logical font size. The default is 8.

Params:
size – a non-negative integer between 1 and 72. Any number outside the specified range will be pinned.

  • void setDefaultFontSize(int size)

Sets the default font size. The default is 16.

Params:
size – a non-negative integer between 1 and 72. Any number outside the specified range will be pinned.

  • void setDefaultFixedFontSize(int size)

Sets the default fixed font size. The default is 16.

Params:
size – a non-negative integer between 1 and 72. Any number outside the specified range will be pinned.

  • void setJavascriptEnabled(boolean flag)

Tells the WebView to enable Javascript execution. The default is false.

Params:
flag – true if the WebView should execute Javascript

  • void setGeolocationDatabasePath(String databasePath)

Sets the path where the Geolocation databases should be saved. In order for Geolocation permissions and cached positions to be persisted, this method must be called with a path to which the application can write.

Params:
databasePath – a path to the directory where databases should be saved.

  • void setAppCacheEnabled(boolean flag)

Sets whether the Application Caches API should be enabled. The default is false. Note that in order for the Application Caches API to be enabled, a valid database path must also be supplied to setAppCachePath.

Params:
flag – true if the WebView should enable Application Caches

  • void setAppCachePath(String appCachePath)

Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this method must be called with a path to which the application can write. This method should only be called once: repeated calls are ignored.

Params:
appCachePath – a String path to the directory containing Application Caches files.

  • void setDatabaseEnabled(boolean flag)

Sets whether the database storage API is enabled. The default value is false. See also setDatabasePath for how to correctly set up the database storage API. This setting is global in effect, across all WebView instances in a process. Note you should only modify this setting prior to making any WebView page load within a given process, as the WebView implementation may ignore changes to this setting after that point.

Params:
flag – true if the WebView should use the database storage API

  • void setDomStorageEnabled(boolean flag)

Sets whether the DOM storage API is enabled. The default value is false.

Params:
flag – true if the WebView should use the DOM storage API

  • void setGeolocationEnabled(boolean flag)

Sets whether Geolocation is enabled. The default is true.
Please note that in order for the Geolocation API to be usable by a page in the WebView, the following requirements must be met:
– an application must have permission to access the device location, see android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION;
– an application must provide an implementation of the WebChromeClient.onGeolocationPermissionsShowprompt callback to receive notifications that a page is requesting access to location via the Javascript Geolocation API.
As an option, it is possible to store previous locations and web origin permissions in a database. See setGeolocationDatabasePath.

Params:
flag – whether Geolocation should be enabled

  • void setDefaultTextEncodingName(String encoding)

Sets the default text encoding name to use when decoding html pages. The default is “UTF-8”.

Params:
encoding – the text encoding name

  • void setUserAgentString(String ua)

Sets the WebView’s user-agent string. If the string is null or empty, the system default value will be used. Note that starting from android.os.Build.VERSION_CODES.KITKAT Android version, changing the user-agent while loading a web page causes WebView to initiate loading once again.

Params:
ua – new user-agent string

  • void setNeedInitialFocus(boolean flag)

Tells the WebView whether it needs to set a node to have focus when WebView.requestFocus(int, android.graphics.Rect) is called. The default value is true.

Params:
flag – whether the WebView needs to set a node

  • void setCacheMode(int mode)
    Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. When navigating back, content is not revalidated, instead the content is just retrieved from the cache. This method allows the client to override this behavior by specifying one of LOAD_DEFAULT, LOAD_CACHE_ELSE_NETWORK, LOAD_NO_CACHE or LOAD_CACHE_ONLY. The default value is LOAD_DEFAULT.

Params:
mode – the mode to use

  • void setMixedContentMode(int mode)
    Configures the WebView’s behavior when a secure origin attempts to load a resource from an insecure origin. By default, apps that target android.os.Build.VERSION_CODES.KITKAT or below default to MIXED_CONTENT_ALWAYS_ALLOW. Apps targeting android.os.Build.VERSION_CODES.LOLLIPOP default to MIXED_CONTENT_NEVER_ALLOW. The preferred and most secure mode of operation for the WebView is MIXED_CONTENT_NEVER_ALLOW and use of MIXED_CONTENT_ALWAYS_ALLOW is strongly discouraged.

Params:
mode – The mixed content mode to use. One of MIXED_CONTENT_NEVER_ALLOW, MIXED_CONTENT_ALWAYS_ALLOW or MIXED_CONTENT_COMPATIBILITY_MODE.

  • void setOffscreenPreRaster(boolean enabled)

Sets whether this WebView should raster tiles when it is offscreen but attached to a window. Turning this on can avoid rendering artifacts when animating an offscreen WebView on-screen. Offscreen WebViews in this mode use more memory. The default value is false. Please follow these guidelines to limit memory usage:
WebView size should be not be larger than the device screen size.
Limit use of this mode to a small number of WebViews. Use it for visible WebViews and WebViews about to be animated to visible.

Tricks 常用移动端H5设置
WebSettings settings = webview.getSettings();
settings.setJavascriptEnabled(true);//启用js
settings.setJavascriptCanOpenWindowsAutomatically(true);//js和android交互
settings.setAppCachePath(cacheDirPath); //设置缓存的指定路径
settings.setAllowFileAccess(true); // 允许访问文件
settings.setAppCacheEnabled(true); //设置H5的缓存打开,默认关闭
settings.setUseWideViewPort(true);//设置webview自适应屏幕大小
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);//设置,可能的话使所有列的宽度不超过屏幕宽度
settings.setLoadWithOverviewMode(true);//设置webview自适应屏幕大小
settings.setDomStorageEnabled(true);//设置可以使用localStorage
settings.setSupportZoom(false);//关闭zoom按钮
settings.setBuiltInZoomControls(false);//关闭zoom
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
	webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
缓存模式
  • LOAD_CACHE_ONLY
    不使用网络,只读取本地缓存数据
  • LOAD_DEFAULT:
    根据cache-control决定是否从网络上取数据。
  • LOAD_CACHE_NORMAL
    API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
  • LOAD_NO_CACHE
    不使用缓存,只从网络获取数据.
  • LOAD_CACHE_ELSE_NETWORK
    只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

如:www.taobao.com的cache-control为no-cache,在模式LOAD_DEFAULT下,无论如何都会从网络上取数据,如果没有网络,就会出现错误页面;在LOAD_CACHE_ELSE_NETWORK模式下,无论是否有网络,只要本地有缓存,都使用缓存。本地没有缓存时才从网络上获取。
www.360.com.cn的cache-control为max-age=60,在两种模式下都使用本地缓存数据。

根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK。

WebViewClient API

java doc copied from android api 23.

  • boolean shouldOverrideUrlLoading(WebView view, String url)

Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url. This method is not called for requests using the POST “method”.

Params:
view – The WebView that is initiating the callback.
url – The url to be loaded.
Returns:
True if the host application wants to leave the current WebView and handle the url itself, otherwise return false.

注意:代码调用WebView.loadUrl(url)时此回调是不会被调用的,在网页中点击才会走这个方法

  • void onPageStarted(WebView view, String url, Bitmap favicon)

Notify the host application that a page has started loading. This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted one time for the main frame. This also means that onPageStarted will not be called when the contents of an embedded frame changes, i.e. clicking a link whose target is an iframe, it will also not be called for fragment navigations (navigations to #fragment_id).

Params:
view – The WebView that is initiating the callback.
url – The url to be loaded.
favicon – The favicon for this page if it already exists in the database.

  • void onPageFinished(WebView view, String url)

Notify the host application that a page has finished loading. This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet. To get the notification for the new Picture, use WebView.PictureListener.onNewPicture.

Params:
view – The WebView that is initiating the callback.
url – The url of the page.

  • void onLoadResource(WebView view, String url)

Notify the host application that the WebView will load the resource specified by the given url.

Params:
view – The WebView that is initiating the callback.
url – The url of the resource the WebView will load.

  • void onPageCommitVisible(WebView view, String url)

Notify the host application that WebView content left over from previous page navigations will no longer be drawn.
This callback can be used to determine the point at which it is safe to make a recycled WebView visible, ensuring that no stale content is shown. It is called at the earliest point at which it can be guaranteed that WebView.onDraw will no longer draw any content from previous navigations. The next draw will display either the background color of the WebView, or some of the contents of the newly loaded page.
This method is called when the body of the HTTP response has started loading, is reflected in the DOM, and will be visible in subsequent draws. This callback occurs early in the document loading process, and as such you should expect that linked resources (for example, css and images) may not be available.
For more fine-grained notification of visual state updates, see WebView.postVisualStateCallback.
Please note that all the conditions and recommendations applicable to WebView.postVisualStateCallback also apply to this API.
This callback is only called for main frame navigations.

Params:
view – The WebView for which the navigation occurred.
url – The URL corresponding to the page navigation that triggered this callback.

  • WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)

Notify the host application of a resource request and allow the application to return the data. If the return value is null, the WebView will continue to load the resource as usual. Otherwise, the return response and data will be used. NOTE: This method is called on a thread other than the UI thread so clients should exercise caution when accessing private data or the view system.

Params:
view – The WebView that is requesting the resource.
request – Object containing the details of the request.
Returns:
A WebResourceResponse containing the response information or null if the WebView should load the resource itself.

  • void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)
    Report web resource loading error to the host application. These errors usually indicate inability to connect to the server. Note that unlike the deprecated version of the callback, the new version will be called for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to perform minimum required work in this callback.

Params:
view – The WebView that is initiating the callback.
request – The originating request.
error – Information about the error occured.

  • void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)

Notify the host application that an HTTP error has been received from the server while loading a resource. HTTP errors have status codes >= 400. This callback will be called for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to perform minimum required work in this callback. Note that the content of the server response may not be provided within the errorResponse parameter.

Params:
view – The WebView that is initiating the callback.
request – The originating request.
errorResponse – Information about the error occured.

  • void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)

Notify the host application that an SSL error occurred while loading a resource. The host application must call either handler.cancel() or handler.proceed(). Note that the decision may be retained for use in response to future SSL errors. The default behavior is to cancel the load.

Params:
view – The WebView that is initiating the callback.
handler – An SslErrorHandler object that will handle the user’s response.
error – The SSL error object.

  • void onFormResubmission(WebView view, Message dontResend, Message resend)

As the host application if the browser should resend data as the requested page was a result of a POST. The default is to not resend the data.

Params:
view – The WebView that is initiating the callback.
dontResend – The message to send if the browser should not resend
resend – The message to send if the browser should resend data

  • void doUpdateVisitedHistory(WebView view, String url, boolean isReload)

Notify the host application to update its visited links database.

Params:
view – The WebView that is initiating the callback.
url – The url being visited.
isReload – True if this url is being reloaded.

  • void onReceivedClientCertRequest(WebView view, ClientCertRequest request)

Notify the host application to handle a SSL client certificate request. The host application is responsible for showing the UI if desired and providing the keys. There are three ways to respond: proceed(), cancel() or ignore(). Webview stores the response in memory (for the life of the application) if proceed() or cancel() is called and does not call onReceivedClientCertRequest() again for the same host and port pair. Webview does not store the response if ignore() is called. This method is called on the UI thread. During the callback, the connection is suspended. For most use cases, the application program should implement the android.security.KeyChainAliasCallback interface and pass it to android.security.KeyChain.choosePrivateKeyAlias to start an activity for the user to choose the proper alias. The keychain activity will provide the alias through the callback method in the implemented interface. Next the application should create an async task to call android.security.KeyChain.getPrivateKey to receive the key. An example implementation of client certificates can be seen at AOSP Browser The default behavior is to cancel, returning no client certificate.

Params:
view – The WebView that is initiating the callback
request – An instance of a ClientCertRequest

  • void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)

Notifies the host application that the WebView received an HTTP authentication request. The host application can use the supplied HttpAuthHandler to set the WebView’s response to the request. The default behavior is to cancel the request.

Params:
view – the WebView that is initiating the callback
handler – the HttpAuthHandler used to set the WebView’s response
host – the host requiring authentication
realm – the realm for which authentication is required
See Also:
WebView.getHttpAuthUsernamePassword

  • void onReceivedLoginRequest(WebView view, String realm, String account, String args)

Notify the host application that a request to automatically log in the user has been processed.

Params:
view – The WebView requesting the login.
realm – The account realm used to look up accounts.
account – An optional account. If not null, the account should be checked against accounts on the device. If it is a valid account, it should be used to log in the user.
args – Authenticator specific arguments used to log in the user.

  • public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)

Give the host application a chance to handle the key event synchronously. e.g. menu shortcut key events need to be filtered this way. If return true, WebView will not handle the key event. If return false, WebView will always handle the key event, so none of the super in the view chain will see the key event. The default behavior returns false.

Params:
view – The WebView that is initiating the callback.
event – The key event.
Returns:
True if the host application wants to handle the key event itself, otherwise return false

  • void onUnhandledInputEvent(WebView view, InputEvent event)

Notify the host application that a input event was not handled by the WebView. Except system keys, WebView always consumes input events in the normal flow or if shouldOverrideKeyEvent returns true. This is called asynchronously from where the event is dispatched. It gives the host application a chance to handle the unhandled input events. Note that if the event is a android.view.MotionEvent, then it’s lifetime is only that of the function call. If the WebViewClient wishes to use the event beyond that, then it must create a copy of the event. It is the responsibility of overriders of this method to call onUnhandledKeyEvent(WebView, KeyEvent) when appropriate if they wish to continue receiving events through it.

Params:
view – The WebView that is initiating the callback.
event – The input event.

  • void onScaleChanged(WebView view, float oldScale, float newScale)

Notify the host application that the scale applied to the WebView has changed.

Params:
view – the WebView that is initiating the callback.
oldScale – The old scale factor
newScale – The new scale factor

Tricks 高频拦截接口
  • shouldOverrideUrlLoading:拦截除资源请求的url,此处可以解析做自定义跳转
  • shouldInterceptRequest:拦截所有url请求,包括超链接、JS文件、CSS文件、图片等,注意此回调非主线程,此处可以做资源替换和预加载
WebChromeClient API
  • void onProgressChanged(WebView view, int newProgress)

Tell the host application the current progress of loading a page.

Params:
view – The WebView that initiated the callback.
newProgress – Current page loading progress, represented by an integer between 0 and 100.

  • void onReceivedTitle(WebView view, String title)

Notify the host application of a change in the document title.

Params:
view – The WebView that initiated the callback.
title – A String containing the new title of the document.

  • void onReceivedIcon(WebView view, Bitmap icon)

Notify the host application of a new favicon for the current page.

Params:
view – The WebView that initiated the callback.
icon – A Bitmap containing the favicon for the current page.

  • void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)

Notify the host application of the url for an apple-touch-icon.

Params:
view – The WebView that initiated the callback.
url – The icon url.
precomposed – True if the url is for a precomposed touch icon.

  • void onShowCustomView(View view, CustomViewCallback callback)

Notify the host application that the current page has entered full screen mode. The host application must show the custom View which contains the web contents — video or other HTML content — in full screen mode. Also see “Full screen support” documentation on WebView.

Params:
view – is the View object to be shown.
callback – invoke this callback to request the page to exit full screen mode.

当 H5 页面中点击播放的 flash video 的全屏按钮时,会调用这个方法

  • void onHideCustomView()

Notify the host application that the current page has exited full screen mode. The host application must hide the custom View, ie. the View passed to onShowCustomView when the content entered fullscreen. Also see “Full screen support” documentation on WebView.

与 onShowCustomView() 对应的取消全屏时会调用的方法

  • boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)

Request the host application to create a new window. If the host application chooses to honor this request, it should return true from this method, create a new WebView to host the window, insert it into the View system and send the supplied resultMsg message to its target with the new WebView as an argument. If the host application chooses not to honor the request, it should return false from this method. The default implementation of this method does nothing and hence returns false.

Params:
view – The WebView from which the request for a new window originated.
isDialog – True if the new window should be a dialog, rather than a full-size window.
isUserGesture – True if the request was initiated by a user gesture, such as the user clicking a link.
resultMsg – The message to send when once a new WebView has been created. resultMsg.obj is a WebView.WebViewTransport object. This should be used to transport the new WebView, by calling WebView.WebViewTransport.setWebView(WebView).
Returns:
This method should return true if the host application will create a new window, in which case resultMsg should be sent to its target. Otherwise, this method should return false. Returning false from this method but also sending resultMsg will result in undefined behavior.

类似于浏览器open with new tab

  • void onCloseWindow(WebView window)

Notify the host application to close the given WebView and remove it from the view system if necessary. At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.

Params:
window – The WebView that needs to be closed.

  • void onRequestFocus(WebView view)

Request display and focus for this WebView. This may happen due to another WebView opening a link in this WebView and requesting that this WebView be displayed.

Params:
view – The WebView that needs to be focused.

  • boolean onJsalert(WebView view, String url, String message, JsResult result)

Tell the client to display a javascript alert dialog. If the client returns true, WebView will assume that the client will handle the dialog. If the client returns false, it will continue execution.

Params:
view – The WebView that initiated the callback.
url – The url of the page requesting the dialog.
message – Message to be displayed in the window.
result – A JsResult to confirm that the user hit enter.
Returns:
boolean Whether the client will handle the alert dialog.

alertd窗:只有一个确认按钮

  • boolean onJs/confirm/i(WebView view, String url, String message, JsResult result)

Tell the client to display a confirm dialog to the user. If the client returns true, WebView will assume that the client will handle the confirm dialog and call the appropriate JsResult method. If the client returns false, a default value of false will be returned to javascript. The default behavior is to return false.

Params:
view – The WebView that initiated the callback.
url – The url of the page requesting the dialog.
message – Message to be displayed in the window.
result – A JsResult used to send the user’s response to javascript.

/confirm/id窗:确认和取消按钮

  • boolean onJsprompt(WebView view, String url, String message, String defaultValue, JspromptResult result)

Tell the client to display a prompt dialog to the user. If the client returns true, WebView will assume that the client will handle the prompt dialog and call the appropriate JspromptResult method. If the client returns false, a default value of false will be returned to to javascript. The default behavior is to return false.

Params:
view – The WebView that initiated the callback.
url – The url of the page requesting the dialog.
message – Message to be displayed in the window.
defaultValue – The default value displayed in the prompt dialog.
result – A JspromptResult used to send the user’s reponse to javascript.
Returns:
boolean Whether the client will handle the prompt dialog.

promptd窗:通常带有用户输入

  • boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result)

Tell the client to display a dialog to confirm navigation away from the current page. This is the result of the onbeforeunload javascript event. If the client returns true, WebView will assume that the client will handle the confirm dialog and call the appropriate JsResult method. If the client returns false, a default value of true will be returned to javascript to accept navigation away from the current page. The default behavior is to return false. Setting the JsResult to true will navigate away from the current page, false will cancel the navigation.

Params:
view – The WebView that initiated the callback.
url – The url of the page requesting the dialog.
message – Message to be displayed in the window.
result – A JsResult used to send the user’s response to javascript.
Returns:
boolean Whether the client will handle the confirm dialog.

  • void onGeolocationPermissionsShowprompt(String origin, GeolocationPermissions.Callback callback)

Notify the host application that web content from the specified origin is attempting to use the Geolocation API, but no permission state is currently set for that origin. The host application should invoke the specified callback with the desired permission state. See GeolocationPermissions for details.

Params:
origin – The origin of the web content attempting to use the Geolocation API.
callback – The callback to use to set the permission state for the origin.

  • void onGeolocationPermissionsHideprompt()

Notify the host application that a request for Geolocation permissions, made with a previous call to onGeolocationPermissionsShowprompt() has been canceled. Any related UI should therefore be hidden.

  • void onPermissionRequest(PermissionRequest request)

Notify the host application that web content is requesting permission to access the specified resources and the permission currently isn’t granted or denied. The host application must invoke PermissionRequest.grant(String[]) or PermissionRequest.deny(). If this method isn’t overridden, the permission is denied.

Params:
request – the PermissionRequest from current web content.

  • void onPermissionRequestCanceled(PermissionRequest request)

Notify the host application that the given permission request has been canceled. Any related UI should therefore be hidden.

Params:
request – the PermissionRequest that needs be canceled.

  • boolean onConsoleMessage(ConsoleMessage consoleMessage)

Report a Javascript console message to the host application. The ChromeClient should override this to process the log message as they see fit.

Params:
consoleMessage – Object containing details of the console message.
Returns:
true if the message is handled by the client.

  • Bitmap getDefaultVideoPoster()

When not playing, video elements are represented by a ‘poster’ image. The image to use can be specified by the poster attribute of the video tag in HTML. If the attribute is absent, then a default poster will be used. This method allows the ChromeClient to provide that default image.

Returns:
Bitmap The image to use as a default poster, or null if no such image is available.

  • View getVideoLoadingProgressView()

Obtains a View to be displayed while buffering of full screen video is taking place. The host application can override this method to provide a View containing a spinner or similar.

Returns:
View The View to be displayed whilst the video is loading.

  • void getVisitedHistory(ValueCallback callback)

Obtains a list of all visited history items, used for link coloring

  • boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams)

Tell the client to show a file chooser. This is called to handle HTML forms with ‘file’ input type, in response to the user pressing the “Select File” button. To cancel the request, call filePathCallback.onReceivevalue(null) and return true.

Params:
webView – The WebView instance that is initiating the request.
filePathCallback – Invoke this callback to supply the list of paths to files to upload, or NULL to cancel. Must only be called if the showFileChooser implementations returns true.
fileChooserParams – Describes the mode of file chooser to be opened, and options to be used with it.
Returns:
true if filePathCallback will be invoked, false to use default handling.

Tricks WebChromeClient与WebViewClient区别

相信你跟我一样十分不理解为什么安卓webview要搞两个client来处理相关事务,其实WebView的内部实现并不是完全使用Chrome的内核,而是部分使用Chome内核,其它都是与Chrome不相同的。

  • WebViewClient:在影响View的事件到来时,会通过WebViewClient中的方法回调通知用户
  • WebChromeClient:当影响浏览器的事件到来时,就会通过WebChromeClient中的方法回调通知用法。

总之,WebViewClient和WebChromeClient都是一堆针对不同事件的回调,而google将这些回调进行分类集合,就产生了WebViewClient、WebChromeClient这两个大类,其中管理着针对不同类型的回调而已。

例如:

  • 只需要加上mWebView.setWebChromeClient(new WebChromeClient());就可以实现confrim()、alert()、prompt()的d出效果了。除了alert,prompt,/confirm/i以外,其它时候都不需要强制设置WebChromeClient。
  • 页面中含有连接,点击链接如果想继续在当前浏览器中浏览网页则需要重写 WebView 的 WebViewClient ,并实现shouldOverrideUrlLoading接口,否则默认的行为是会在手机系统自带的浏览器中打开新的链接。
cookieManager WebStorage 原生通讯 原生调JS
// 调用JS
// 调用一个已定义的JS方法:
String jsUri="javascript:getText()";
// 调用一个未定义过的JS方法:
// String jsUri="javascript:(function getText(){...})()";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
	// 相较于loadUrl,evaluateJavascript的优势在于异步加载,还可以将执行JS代码的结果带回来
	mWebView.evaluateJavascript(jsUri, null);
} else {
	mWebView.loadUrl(jsUri);
}

原生调用JS很关键的一点是注入的时机,在 Activity 的 onCreate() 方法中直接调用 WebView.loadUrl() 方法是不会生效的,需要在WebView 加载完成之后再调用 Js 的代码才会生效。通常推荐的自动注入入口是:

  • WebClient#onPageStarted()
  • WebClient#onPageFinished()
JS调原生 JavascriptInterface方案

首先原生定义一个通讯接口:

webView.addJavascriptInterface(new Object(){
	@JavascriptInterface
    public void toast(String msg) {
        ToastUtils.toast(msg);
    }
}, "namespace");

然后H5端调用:

function testprompt(){
      window.namespace.toast("jsbridge");
}
iframe+schema拦截方案

url拦截这部分内容我们比较熟悉了,就是前面提到的WebViewClient#shouldOverrideUrlLoading回调以及WebChromeClient#onJsprompt回调。

还是直接看例子:
一个只有button的H5页面如下:




    
    Title
    



					
										


					

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5481807.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存