Loading core/java/android/webkit/WebView.java +13 −268 Original line number Diff line number Diff line Loading @@ -70,280 +70,25 @@ import java.util.List; import java.util.Map; /** * <p>A View that displays web pages. This class is the basis upon which you * can roll your own web browser or simply display some online content within your Activity. * It uses the WebKit rendering engine to display * web pages and includes methods to navigate forward and backward * through a history, zoom in and out, perform text searches and more. * * <p>Note that, in order for your Activity to access the Internet and load web pages * in a WebView, you must add the {@code INTERNET} permissions to your * Android Manifest file: * * <pre> * {@code <uses-permission android:name="android.permission.INTERNET" />} * </pre> * * <p>This must be a child of the <a * href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code <manifest>}</a> * element. * * <p>For more information, read * <a href="{@docRoot}guide/webapps/webview.html">Building Web Apps in WebView</a>. * A View that displays web pages. * * <h3>Basic usage</h3> * * <p>By default, a WebView provides no browser-like widgets, does not * enable JavaScript and web page errors are ignored. If your goal is only * to display some HTML as a part of your UI, this is probably fine; * the user won't need to interact with the web page beyond reading * it, and the web page won't need to interact with the user. If you * actually want a full-blown web browser, then you probably want to * invoke the Browser application with a URL Intent rather than show it * with a WebView. For example: * <pre> * Uri uri = Uri.parse("https://www.example.com"); * Intent intent = new Intent(Intent.ACTION_VIEW, uri); * startActivity(intent); * </pre> * <p>See {@link android.content.Intent} for more information. * * <p>To provide a WebView in your own Activity, include a {@code <WebView>} in your layout, * or set the entire Activity window as a WebView during {@link * android.app.Activity#onCreate(Bundle) onCreate()}: * * <pre class="prettyprint"> * WebView webview = new WebView(this); * setContentView(webview); * </pre> * * <p>Then load the desired web page: * * <pre> * // Simplest usage: note that an exception will NOT be thrown * // if there is an error loading this page (see below). * webview.loadUrl("https://example.com/"); * * // OR, you can also load from an HTML string: * String summary = "<html><body>You scored <b>192</b> points.</body></html>"; * webview.loadData(summary, "text/html", null); * // ... although note that there are restrictions on what this HTML can do. * // See {@link #loadData(String,String,String)} and {@link * #loadDataWithBaseURL(String,String,String,String,String)} for more info. * // Also see {@link #loadData(String,String,String)} for information on encoding special * // characters. * </pre> * * <p>A WebView has several customization points where you can add your * own behavior. These are: * * <ul> * <li>Creating and setting a {@link android.webkit.WebChromeClient} subclass. * This class is called when something that might impact a * browser UI happens, for instance, progress updates and * JavaScript alerts are sent here (see <a * href="{@docRoot}guide/webapps/debugging.html">Debugging Web Apps</a>). * </li> * <li>Creating and setting a {@link android.webkit.WebViewClient} subclass. * It will be called when things happen that impact the * rendering of the content, eg, errors or form submissions. You * can also intercept URL loading here (via {@link * android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) * shouldOverrideUrlLoading()}).</li> * <li>Modifying the {@link android.webkit.WebSettings}, such as * enabling JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean) * setJavaScriptEnabled()}. </li> * <li>Injecting Java objects into the WebView using the * {@link android.webkit.WebView#addJavascriptInterface} method. This * method allows you to inject Java objects into a page's JavaScript * context, so that they can be accessed by JavaScript in the page.</li> * </ul> * * <p>Here's a more complicated example, showing error handling, * settings, and progress notification: * * <pre class="prettyprint"> * // Let's display the progress in the activity title bar, like the * // browser app does. * getWindow().requestFeature(Window.FEATURE_PROGRESS); * * webview.getSettings().setJavaScriptEnabled(true); * * final Activity activity = this; * webview.setWebChromeClient(new WebChromeClient() { * public void onProgressChanged(WebView view, int progress) { * // Activities and WebViews measure progress with different scales. * // The progress meter will automatically disappear when we reach 100% * activity.setProgress(progress * 1000); * } * }); * webview.setWebViewClient(new WebViewClient() { * public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { * Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show(); * } * }); * * webview.loadUrl("https://developer.android.com/"); * </pre> * * <h3>Zoom</h3> * * <p>To enable the built-in zoom, set * {@link #getSettings() WebSettings}.{@link WebSettings#setBuiltInZoomControls(boolean)} * (introduced in API level {@link android.os.Build.VERSION_CODES#CUPCAKE}). * * <p class="note"><b>Note:</b> Using zoom if either the height or width is set to * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} may lead to undefined behavior * and should be avoided. * * <h3>Cookie and window management</h3> * * <p>For obvious security reasons, your application has its own * cache, cookie store etc.—it does not share the Browser * application's data. * * <p>By default, requests by the HTML to open new windows are * ignored. This is {@code true} whether they be opened by JavaScript or by * the target attribute on a link. You can customize your * {@link WebChromeClient} to provide your own behavior for opening multiple windows, * and render them in whatever manner you want. * * <p>The standard behavior for an Activity is to be destroyed and * recreated when the device orientation or any other configuration changes. This will cause * the WebView to reload the current page. If you don't want that, you * can set your Activity to handle the {@code orientation} and {@code keyboardHidden} * changes, and then just leave the WebView alone. It'll automatically * re-orient itself as appropriate. Read <a * href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a> for * more information about how to handle configuration changes during runtime. * * * <h3>Building web pages to support different screen densities</h3> * * <p>The screen density of a device is based on the screen resolution. A screen with low density * has fewer available pixels per inch, where a screen with high density * has more — sometimes significantly more — pixels per inch. The density of a * screen is important because, other things being equal, a UI element (such as a button) whose * height and width are defined in terms of screen pixels will appear larger on the lower density * screen and smaller on the higher density screen. * For simplicity, Android collapses all actual screen densities into three generalized densities: * high, medium, and low. * <p>By default, WebView scales a web page so that it is drawn at a size that matches the default * appearance on a medium density screen. So, it applies 1.5x scaling on a high density screen * (because its pixels are smaller) and 0.75x scaling on a low density screen (because its pixels * are bigger). * Starting with API level {@link android.os.Build.VERSION_CODES#ECLAIR}, WebView supports DOM, CSS, * and meta tag features to help you (as a web developer) target screens with different screen * densities. * <p>Here's a summary of the features you can use to handle different screen densities: * <ul> * <li>The {@code window.devicePixelRatio} DOM property. The value of this property specifies the * default scaling factor used for the current device. For example, if the value of {@code * window.devicePixelRatio} is "1.0", then the device is considered a medium density (mdpi) device * and default scaling is not applied to the web page; if the value is "1.5", then the device is * considered a high density device (hdpi) and the page content is scaled 1.5x; if the * value is "0.75", then the device is considered a low density device (ldpi) and the content is * scaled 0.75x.</li> * <li>The {@code -webkit-device-pixel-ratio} CSS media query. Use this to specify the screen * densities for which this style sheet is to be used. The corresponding value should be either * "0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium * density, or high density screens, respectively. For example: * <pre> * <link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1.5)" href="hdpi.css" /></pre> * <p>The {@code hdpi.css} stylesheet is only used for devices with a screen pixel ratio of 1.5, * which is the high density pixel ratio. * </li> * </ul> * * <h3>HTML5 Video support</h3> * * <p>In order to support inline HTML5 video in your application you need to have hardware * acceleration turned on. * * <h3>Full screen support</h3> * * <p>In order to support full screen — for video or other HTML content — you need to set a * {@link android.webkit.WebChromeClient} and implement both * {@link WebChromeClient#onShowCustomView(View, WebChromeClient.CustomViewCallback)} * and {@link WebChromeClient#onHideCustomView()}. If the implementation of either of these two methods is * missing then the web contents will not be allowed to enter full screen. Optionally you can implement * {@link WebChromeClient#getVideoLoadingProgressView()} to customize the View displayed whilst a video * is loading. * * <h3>HTML5 Geolocation API support</h3> * * <p>For applications targeting Android N and later releases * (API level > {@link android.os.Build.VERSION_CODES#M}) the geolocation api is only supported on * secure origins such as https. For such applications requests to geolocation api on non-secure * origins are automatically denied without invoking the corresponding * {@link WebChromeClient#onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback)} * method. * * <h3>Layout size</h3> * <p> * It is recommended to set the WebView layout height to a fixed value or to * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} instead of using * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}. * When using {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} * for the height none of the WebView's parents should use a * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} layout height since that could result in * incorrect sizing of the views. * * <p>Setting the WebView's height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} * enables the following behaviors: * <ul> * <li>The HTML body layout height is set to a fixed value. This means that elements with a height * relative to the HTML body may not be sized correctly. </li> * <li>For applications targeting {@link android.os.Build.VERSION_CODES#KITKAT} and earlier SDKs the * HTML viewport meta tag will be ignored in order to preserve backwards compatibility. </li> * </ul> * * <p> * Using a layout width of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} is not * supported. If such a width is used the WebView will attempt to use the width of the parent * instead. * * <h3>Metrics</h3> * * <p> * WebView may upload anonymous diagnostic data to Google when the user has consented. This data * helps Google improve WebView. Data is collected on a per-app basis for each app which has * instantiated a WebView. An individual app can opt out of this feature by putting the following * tag in its manifest's {@code <application>} element: * <pre> * <manifest> * <application> * ... * <meta-data android:name="android.webkit.WebView.MetricsOptOut" * android:value="true" /> * </application> * </manifest> * </pre> * <p> * Data will only be uploaded for a given app if the user has consented AND the app has not opted * out. * <p>In most cases, we recommend using a standard web browser, like Chrome, to deliver * content to the user. To learn more about web browsers, read the guide on * <a href="/guide/components/intents-common#Browser"> * invoking a browser with an intent</a>. * * <h3>Safe Browsing</h3> * <p>WebView objects allow you to display web content as part of your activity layout, but * lack some of the features of fully-developed browsers. A WebView is useful when * you need increased control over the UI and advanced configuration options that will allow * you to embed web pages in a specially-designed environment for your app. * * <p> * With Safe Browsing, WebView will block malicious URLs and present a warning UI to the user to * allow them to navigate back safely or proceed to the malicious page. * <p> * Safe Browsing is enabled by default on devices which support it. If your app needs to disable * Safe Browsing for all WebViews, it can do so in the manifest's {@code <application>} element: * <p> * <pre> * <manifest> * <application> * ... * <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" * android:value="false" /> * </application> * </manifest> * </pre> * * <p> * Otherwise, see {@link WebSettings#setSafeBrowsingEnabled}. * <p>To learn more about WebView and alternatives for serving web content, read the * documentation on * <a href="/guide/webapps/"> * Web-based content</a>. * */ // Implementation notes. Loading Loading
core/java/android/webkit/WebView.java +13 −268 Original line number Diff line number Diff line Loading @@ -70,280 +70,25 @@ import java.util.List; import java.util.Map; /** * <p>A View that displays web pages. This class is the basis upon which you * can roll your own web browser or simply display some online content within your Activity. * It uses the WebKit rendering engine to display * web pages and includes methods to navigate forward and backward * through a history, zoom in and out, perform text searches and more. * * <p>Note that, in order for your Activity to access the Internet and load web pages * in a WebView, you must add the {@code INTERNET} permissions to your * Android Manifest file: * * <pre> * {@code <uses-permission android:name="android.permission.INTERNET" />} * </pre> * * <p>This must be a child of the <a * href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code <manifest>}</a> * element. * * <p>For more information, read * <a href="{@docRoot}guide/webapps/webview.html">Building Web Apps in WebView</a>. * A View that displays web pages. * * <h3>Basic usage</h3> * * <p>By default, a WebView provides no browser-like widgets, does not * enable JavaScript and web page errors are ignored. If your goal is only * to display some HTML as a part of your UI, this is probably fine; * the user won't need to interact with the web page beyond reading * it, and the web page won't need to interact with the user. If you * actually want a full-blown web browser, then you probably want to * invoke the Browser application with a URL Intent rather than show it * with a WebView. For example: * <pre> * Uri uri = Uri.parse("https://www.example.com"); * Intent intent = new Intent(Intent.ACTION_VIEW, uri); * startActivity(intent); * </pre> * <p>See {@link android.content.Intent} for more information. * * <p>To provide a WebView in your own Activity, include a {@code <WebView>} in your layout, * or set the entire Activity window as a WebView during {@link * android.app.Activity#onCreate(Bundle) onCreate()}: * * <pre class="prettyprint"> * WebView webview = new WebView(this); * setContentView(webview); * </pre> * * <p>Then load the desired web page: * * <pre> * // Simplest usage: note that an exception will NOT be thrown * // if there is an error loading this page (see below). * webview.loadUrl("https://example.com/"); * * // OR, you can also load from an HTML string: * String summary = "<html><body>You scored <b>192</b> points.</body></html>"; * webview.loadData(summary, "text/html", null); * // ... although note that there are restrictions on what this HTML can do. * // See {@link #loadData(String,String,String)} and {@link * #loadDataWithBaseURL(String,String,String,String,String)} for more info. * // Also see {@link #loadData(String,String,String)} for information on encoding special * // characters. * </pre> * * <p>A WebView has several customization points where you can add your * own behavior. These are: * * <ul> * <li>Creating and setting a {@link android.webkit.WebChromeClient} subclass. * This class is called when something that might impact a * browser UI happens, for instance, progress updates and * JavaScript alerts are sent here (see <a * href="{@docRoot}guide/webapps/debugging.html">Debugging Web Apps</a>). * </li> * <li>Creating and setting a {@link android.webkit.WebViewClient} subclass. * It will be called when things happen that impact the * rendering of the content, eg, errors or form submissions. You * can also intercept URL loading here (via {@link * android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) * shouldOverrideUrlLoading()}).</li> * <li>Modifying the {@link android.webkit.WebSettings}, such as * enabling JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean) * setJavaScriptEnabled()}. </li> * <li>Injecting Java objects into the WebView using the * {@link android.webkit.WebView#addJavascriptInterface} method. This * method allows you to inject Java objects into a page's JavaScript * context, so that they can be accessed by JavaScript in the page.</li> * </ul> * * <p>Here's a more complicated example, showing error handling, * settings, and progress notification: * * <pre class="prettyprint"> * // Let's display the progress in the activity title bar, like the * // browser app does. * getWindow().requestFeature(Window.FEATURE_PROGRESS); * * webview.getSettings().setJavaScriptEnabled(true); * * final Activity activity = this; * webview.setWebChromeClient(new WebChromeClient() { * public void onProgressChanged(WebView view, int progress) { * // Activities and WebViews measure progress with different scales. * // The progress meter will automatically disappear when we reach 100% * activity.setProgress(progress * 1000); * } * }); * webview.setWebViewClient(new WebViewClient() { * public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { * Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show(); * } * }); * * webview.loadUrl("https://developer.android.com/"); * </pre> * * <h3>Zoom</h3> * * <p>To enable the built-in zoom, set * {@link #getSettings() WebSettings}.{@link WebSettings#setBuiltInZoomControls(boolean)} * (introduced in API level {@link android.os.Build.VERSION_CODES#CUPCAKE}). * * <p class="note"><b>Note:</b> Using zoom if either the height or width is set to * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} may lead to undefined behavior * and should be avoided. * * <h3>Cookie and window management</h3> * * <p>For obvious security reasons, your application has its own * cache, cookie store etc.—it does not share the Browser * application's data. * * <p>By default, requests by the HTML to open new windows are * ignored. This is {@code true} whether they be opened by JavaScript or by * the target attribute on a link. You can customize your * {@link WebChromeClient} to provide your own behavior for opening multiple windows, * and render them in whatever manner you want. * * <p>The standard behavior for an Activity is to be destroyed and * recreated when the device orientation or any other configuration changes. This will cause * the WebView to reload the current page. If you don't want that, you * can set your Activity to handle the {@code orientation} and {@code keyboardHidden} * changes, and then just leave the WebView alone. It'll automatically * re-orient itself as appropriate. Read <a * href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a> for * more information about how to handle configuration changes during runtime. * * * <h3>Building web pages to support different screen densities</h3> * * <p>The screen density of a device is based on the screen resolution. A screen with low density * has fewer available pixels per inch, where a screen with high density * has more — sometimes significantly more — pixels per inch. The density of a * screen is important because, other things being equal, a UI element (such as a button) whose * height and width are defined in terms of screen pixels will appear larger on the lower density * screen and smaller on the higher density screen. * For simplicity, Android collapses all actual screen densities into three generalized densities: * high, medium, and low. * <p>By default, WebView scales a web page so that it is drawn at a size that matches the default * appearance on a medium density screen. So, it applies 1.5x scaling on a high density screen * (because its pixels are smaller) and 0.75x scaling on a low density screen (because its pixels * are bigger). * Starting with API level {@link android.os.Build.VERSION_CODES#ECLAIR}, WebView supports DOM, CSS, * and meta tag features to help you (as a web developer) target screens with different screen * densities. * <p>Here's a summary of the features you can use to handle different screen densities: * <ul> * <li>The {@code window.devicePixelRatio} DOM property. The value of this property specifies the * default scaling factor used for the current device. For example, if the value of {@code * window.devicePixelRatio} is "1.0", then the device is considered a medium density (mdpi) device * and default scaling is not applied to the web page; if the value is "1.5", then the device is * considered a high density device (hdpi) and the page content is scaled 1.5x; if the * value is "0.75", then the device is considered a low density device (ldpi) and the content is * scaled 0.75x.</li> * <li>The {@code -webkit-device-pixel-ratio} CSS media query. Use this to specify the screen * densities for which this style sheet is to be used. The corresponding value should be either * "0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium * density, or high density screens, respectively. For example: * <pre> * <link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1.5)" href="hdpi.css" /></pre> * <p>The {@code hdpi.css} stylesheet is only used for devices with a screen pixel ratio of 1.5, * which is the high density pixel ratio. * </li> * </ul> * * <h3>HTML5 Video support</h3> * * <p>In order to support inline HTML5 video in your application you need to have hardware * acceleration turned on. * * <h3>Full screen support</h3> * * <p>In order to support full screen — for video or other HTML content — you need to set a * {@link android.webkit.WebChromeClient} and implement both * {@link WebChromeClient#onShowCustomView(View, WebChromeClient.CustomViewCallback)} * and {@link WebChromeClient#onHideCustomView()}. If the implementation of either of these two methods is * missing then the web contents will not be allowed to enter full screen. Optionally you can implement * {@link WebChromeClient#getVideoLoadingProgressView()} to customize the View displayed whilst a video * is loading. * * <h3>HTML5 Geolocation API support</h3> * * <p>For applications targeting Android N and later releases * (API level > {@link android.os.Build.VERSION_CODES#M}) the geolocation api is only supported on * secure origins such as https. For such applications requests to geolocation api on non-secure * origins are automatically denied without invoking the corresponding * {@link WebChromeClient#onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback)} * method. * * <h3>Layout size</h3> * <p> * It is recommended to set the WebView layout height to a fixed value or to * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} instead of using * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}. * When using {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} * for the height none of the WebView's parents should use a * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} layout height since that could result in * incorrect sizing of the views. * * <p>Setting the WebView's height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} * enables the following behaviors: * <ul> * <li>The HTML body layout height is set to a fixed value. This means that elements with a height * relative to the HTML body may not be sized correctly. </li> * <li>For applications targeting {@link android.os.Build.VERSION_CODES#KITKAT} and earlier SDKs the * HTML viewport meta tag will be ignored in order to preserve backwards compatibility. </li> * </ul> * * <p> * Using a layout width of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} is not * supported. If such a width is used the WebView will attempt to use the width of the parent * instead. * * <h3>Metrics</h3> * * <p> * WebView may upload anonymous diagnostic data to Google when the user has consented. This data * helps Google improve WebView. Data is collected on a per-app basis for each app which has * instantiated a WebView. An individual app can opt out of this feature by putting the following * tag in its manifest's {@code <application>} element: * <pre> * <manifest> * <application> * ... * <meta-data android:name="android.webkit.WebView.MetricsOptOut" * android:value="true" /> * </application> * </manifest> * </pre> * <p> * Data will only be uploaded for a given app if the user has consented AND the app has not opted * out. * <p>In most cases, we recommend using a standard web browser, like Chrome, to deliver * content to the user. To learn more about web browsers, read the guide on * <a href="/guide/components/intents-common#Browser"> * invoking a browser with an intent</a>. * * <h3>Safe Browsing</h3> * <p>WebView objects allow you to display web content as part of your activity layout, but * lack some of the features of fully-developed browsers. A WebView is useful when * you need increased control over the UI and advanced configuration options that will allow * you to embed web pages in a specially-designed environment for your app. * * <p> * With Safe Browsing, WebView will block malicious URLs and present a warning UI to the user to * allow them to navigate back safely or proceed to the malicious page. * <p> * Safe Browsing is enabled by default on devices which support it. If your app needs to disable * Safe Browsing for all WebViews, it can do so in the manifest's {@code <application>} element: * <p> * <pre> * <manifest> * <application> * ... * <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" * android:value="false" /> * </application> * </manifest> * </pre> * * <p> * Otherwise, see {@link WebSettings#setSafeBrowsingEnabled}. * <p>To learn more about WebView and alternatives for serving web content, read the * documentation on * <a href="/guide/webapps/"> * Web-based content</a>. * */ // Implementation notes. Loading