Android cung cấp một số API để giúp bạn quản lý
WebView
các đối tượng hiển thị nội dung web trong ứng dụng của bạn.
Trang này mô tả cách sử dụng các API này để làm việc với WebView
đối tượng một cách hiệu quả hơn, nhờ đó cải thiện độ ổn định và tính bảo mật của ứng dụng.
API phiên bản
Kể từ Android 7.0 (API cấp 24), người dùng có thể chọn trong số
các gói khác nhau để hiện nội dung trên web trong đối tượng WebView
.
Lớp AndroidX.webkit
thư viện bao gồm
getCurrentWebViewPackage()
để tìm nạp thông tin liên quan đến gói đang hiển thị web
nội dung trong ứng dụng của bạn. Phương pháp này rất hữu ích khi phân tích các lỗi chỉ xảy ra
khi ứng dụng của bạn cố gắng hiển thị nội dung trên web bằng cách sử dụng
triển khai WebView
.
Để sử dụng phương thức này, hãy thêm logic có trong đoạn mã sau:
Kotlin
val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext) Log.d("MY_APP_TAG", "WebView version: ${webViewPackageInfo.versionName}")
Java
PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext); Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);
Dịch vụ Duyệt web An toàn của Google
Để mang đến cho người dùng trải nghiệm duyệt web an toàn hơn, WebView
bằng cách sử dụng các đối tượng xác minh URL
Tính năng Duyệt web An toàn của Google,
Tính năng này cho phép ứng dụng của bạn hiển thị cảnh báo cho người dùng khi họ cố gắng truy cập vào
trang web có thể không an toàn.
Mặc dù giá trị mặc định của EnableSafeBrowsing
là true, nhưng
là các trường hợp bạn có thể chỉ muốn bật Duyệt web an toàn theo điều kiện hoặc
hãy tắt tính năng đó. Android 8.0 (API cấp 26) trở lên hỗ trợ sử dụng
setSafeBrowsingEnabled()
để bật/tắt tính năng Duyệt web an toàn cho từng đối tượng WebView
.
Nếu bạn muốn tất cả đối tượng WebView
chọn không sử dụng tính năng Duyệt web an toàn
kiểm tra, hãy thêm phần tử <meta-data>
sau vào
tệp kê khai:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
Xác định các hành động có lập trình
Khi một thực thể của WebView
cố gắng tải một trang
được Google phân loại là mối đe doạ đã biết, WebView
theo mặc định
hiển thị một quảng cáo xen kẽ cảnh báo người dùng về mối đe doạ đã biết. Màn hình này cung cấp
cho người dùng lựa chọn vẫn tải URL hoặc quay lại trang trước đó
an toàn.
Nếu nhắm đến Android 8.1 (API cấp 27) trở lên, bạn có thể xác định cách ứng dụng của bạn ứng phó với mối đe doạ đã biết như sau: cách:
- Bạn có thể kiểm soát việc ứng dụng của mình có báo cáo các mối đe doạ đã biết đến chế độ An toàn hay không Duyệt web.
- Bạn có thể đặt để ứng dụng tự động thực hiện một hành động cụ thể, chẳng hạn như như quay lại trang an toàn—mỗi khi gặp một URL được phân loại là mối đe doạ đã biết.
Các đoạn mã sau đây cho biết cách hướng dẫn các thực thể của ứng dụng
WebView
để luôn quay lại an toàn sau khi gặp phải
mối đe doạ:
Kotlin
private lateinit var superSafeWebView: WebView private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this) superSafeWebView.webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) { WebViewCompat.startSafeBrowsing(this, ValueCallback<Boolean> { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) { WebViewCompat.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); } }
Kotlin
class MyWebViewClient : WebViewClientCompat() { // Automatically go "back to safety" when attempting to load a website that // Google identifies as a known threat. An instance of WebView calls this // method only after Safe Browsing is initialized, so there's no conditional // logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponseCompat ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) { callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } } }
Java
public class MyWebViewClient extends WebViewClientCompat { // Automatically go "back to safety" when attempting to load a website that // Google identifies as a known threat. An instance of WebView calls this // method only after Safe Browsing is initialized, so there's no conditional // logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponseCompat callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) { callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } } }
API vị trí địa lý HTML5
Đối với ứng dụng nhắm mục tiêu Android 6.0 (API cấp 23) trở lên, API vị trí địa lý
chỉ được hỗ trợ trên các nguồn gốc bảo mật, chẳng hạn như HTTPS. Mọi yêu cầu đối với
Hệ thống sẽ tự động từ chối API vị trí địa lý trên các nguồn gốc không an toàn mà không gọi
phương thức onGeolocationPermissionsShowPrompt()
tương ứng.
Chọn không thu thập chỉ số
WebView
có thể tải dữ liệu chẩn đoán ẩn danh lên
Google khi người dùng đồng ý. Dữ liệu được thu thập theo từng ứng dụng
cho mỗi ứng dụng tạo thực thể WebView
. Bạn có thể chọn không áp dụng
bằng cách tạo thẻ sau trong tệp kê khai
Phần tử <application>
:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
Dữ liệu chỉ được tải lên từ một ứng dụng nếu người dùng đồng ý và ứng dụng không chọn không tham gia. Để biết thêm thông tin về cách chọn không sử dụng dữ liệu chẩn đoán báo cáo, hãy xem Quyền riêng tư của người dùng trong WebView báo cáo.
API Xử lý việc chấm dứt
Chấm dứt API xử lý các trường hợp trong đó trình kết xuất xử lý một
WebView
đối tượng sẽ biến mất do hệ thống loại bỏ trình kết xuất để lấy lại
bộ nhớ cần thiết hoặc do quá trình kết xuất gặp sự cố. Bằng cách sử dụng API này, bạn
hãy cho phép ứng dụng tiếp tục thực thi, ngay cả khi quy trình kết xuất đã ngừng hoạt động.
Nếu trình kết xuất gặp sự cố trong khi tải một trang web cụ thể, hãy thử
thì việc tải lại cùng một trang đó có thể khiến đối tượng WebView
mới
thể hiện cùng một hành vi sự cố kết xuất hình ảnh.
Đoạn mã sau minh hoạ cách sử dụng API này trong một
Activity
:
Kotlin
inner class MyRendererTrackingWebViewClient : WebViewClient() { private var mWebView: WebView? = null override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean { if (!detail.didCrash()) { // Renderer is killed because the system ran out of memory. The app // can recover gracefully by creating a new WebView instance in the // foreground. Log.e("MY_APP_TAG", ("System killed the WebView rendering process " + "to reclaim memory. Recreating...")) mWebView?.also { webView -> val webViewContainer: ViewGroup = findViewById(R.id.my_web_view_container) webViewContainer.removeView(webView) webView.destroy() mWebView = null } // By this point, the instance variable "mWebView" is guaranteed to // be null, so it's safe to reinitialize it. return true // The app continues executing. } // Renderer crashes because of an internal error, such as a memory // access violation. Log.e("MY_APP_TAG", "The WebView rendering process crashed!") // In this example, the app itself crashes after detecting that the // renderer crashed. If you handle the crash more gracefully and let // your app continue executing, you must destroy the current WebView // instance, specify logic for how the app continues executing, and // return "true" instead. return false } }
Java
public class MyRendererTrackingWebViewClient extends WebViewClient { private WebView mWebView; @Override public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { if (!detail.didCrash()) { // Renderer is killed because the system ran out of memory. The app // can recover gracefully by creating a new WebView instance in the // foreground. Log.e("MY_APP_TAG", "System killed the WebView rendering process " + "to reclaim memory. Recreating..."); if (mWebView != null) { ViewGroup webViewContainer = (ViewGroup) findViewById(R.id.my_web_view_container); webViewContainer.removeView(mWebView); mWebView.destroy(); mWebView = null; } // By this point, the instance variable "mWebView" is guaranteed to // be null, so it's safe to reinitialize it. return true; // The app continues executing. } // Renderer crashes because of an internal error, such as a memory // access violation. Log.e("MY_APP_TAG", "The WebView rendering process crashed!"); // In this example, the app itself crashes after detecting that the // renderer crashed. If you handle the crash more gracefully and let // your app continue executing, you must destroy the current WebView // instance, specify logic for how the app continues executing, and // return "true" instead. return false; } }
API Mức độ quan trọng của trình kết xuất
Khi đối tượng WebView
hoạt động ở
chế độ đa quy trình, nên bạn có thể linh hoạt trong cách ứng dụng của mình xử lý
tình huống hết bộ nhớ. Bạn có thể dùng API Mức độ quan trọng của trình kết xuất, được giới thiệu trong
Android 8.0: thiết lập chính sách ưu tiên cho trình kết xuất được chỉ định cho một trình kết xuất cụ thể
Đối tượng WebView
. Cụ thể, bạn nên thực hiện phần chính
tiếp tục thực thi khi một trình kết xuất hiển thị
WebView
đối tượng đã bị tiêu diệt. Bạn có thể làm việc này, chẳng hạn như nếu bạn
dự kiến sẽ không hiển thị đối tượng WebView
trong một thời gian dài để
hệ thống có thể lấy lại bộ nhớ mà trình kết xuất đang sử dụng.
Đoạn mã sau đây cho biết cách chỉ định mức độ ưu tiên cho trình kết xuất
quy trình liên kết với đối tượng WebView
của ứng dụng:
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
Trong đoạn mã cụ thể này, mức độ ưu tiên của trình kết xuất giống như—hoặc
được liên kết với mức độ ưu tiên mặc định cho ứng dụng. true
đối số giảm mức độ ưu tiên của trình kết xuất xuống
RENDERER_PRIORITY_WAIVED
khi đối tượng WebView
liên kết không còn xuất hiện. Trong khu vực khác
thì đối số true
cho biết ứng dụng của bạn không quan tâm đến việc
hệ thống giúp quá trình kết xuất tiếp tục hoạt động. Trên thực tế, mức độ ưu tiên thấp hơn này
có khả năng quá trình kết xuất đồ hoạ bị dừng khi hết bộ nhớ
ngoại lệ.
Để tìm hiểu thêm về cách hệ thống xử lý các tình huống dung lượng bộ nhớ thấp, hãy xem Quy trình và ứng dụng Lifecycle.