Android มี API มากมายที่จะช่วยคุณจัดการ
WebView
ที่แสดงเนื้อหาเว็บในแอปของคุณ
หน้านี้จะอธิบายวิธีใช้ API เหล่านี้เพื่อทำงานกับ WebView
ออบเจ็กต์ได้อย่างมีประสิทธิภาพมากขึ้น ซึ่งจะช่วยปรับปรุงความเสถียรและความปลอดภัยของแอป
API เวอร์ชัน
เริ่มตั้งแต่ Android 7.0 (API ระดับ 24) เป็นต้นไป ผู้ใช้จะเลือกได้จาก
แพ็กเกจต่างๆ สำหรับการแสดงเนื้อหาเว็บในออบเจ็กต์ WebView
AndroidX.webkit
จะมี
getCurrentWebViewPackage()
วิธีการดึงข้อมูลที่เกี่ยวข้องกับแพ็กเกจที่แสดงเว็บ
เนื้อหาในแอปของคุณ วิธีนี้มีประโยชน์เมื่อวิเคราะห์ข้อผิดพลาดที่เกิดขึ้นเท่านั้น
เมื่อแอปของคุณพยายามแสดงเนื้อหาเว็บโดยใช้แพ็กเกจ
การใช้งาน WebView
หากต้องการใช้วิธีนี้ ให้เพิ่มตรรกะที่แสดงในข้อมูลโค้ดต่อไปนี้
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);
บริการ Google Safe Browsing
เพื่อมอบประสบการณ์การท่องเว็บที่ปลอดภัยยิ่งขึ้นแก่ผู้ใช้ WebView
ออบเจ็กต์ยืนยัน URL โดยใช้
Google Safe Browsing
ซึ่งทำให้แอปของคุณแสดงคำเตือนแก่ผู้ใช้เมื่อพยายามไปที่
เว็บไซต์ที่อาจไม่ปลอดภัย
แม้ว่าค่าเริ่มต้นของ EnableSafeBrowsing
จะเป็นจริง แต่
ในกรณีที่คุณต้องการเปิดใช้ Google Safe Browsing แบบมีเงื่อนไขเท่านั้น หรือ
ปิดใช้ Android 8.0 (API ระดับ 26) ขึ้นไปรองรับการใช้
setSafeBrowsingEnabled()
เพื่อสลับ Google Safe Browsing สำหรับออบเจ็กต์ WebView
แต่ละรายการ
หากคุณต้องการให้ออบเจ็กต์ WebView
ทั้งหมดเลือกไม่ใช้ Google Safe Browsing
ตรวจสอบ ให้เพิ่มองค์ประกอบ <meta-data>
ต่อไปนี้ลงใน
ไฟล์ Manifest:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
กำหนดการทำงานแบบเป็นโปรแกรม
เมื่ออินสแตนซ์ของ WebView
พยายามโหลดหน้าเว็บที่
ที่จัดโดย Google ว่าเป็นภัยคุกคามที่รู้จัก WebView
โดยค่าเริ่มต้น
แสดงโฆษณาคั่นระหว่างหน้าที่เตือนผู้ใช้เกี่ยวกับภัยคุกคามที่ทราบ หน้าจอนี้จะให้
ผู้ใช้สามารถเลือกที่จะโหลด URL ต่อไป หรือกลับไปยังหน้าก่อนหน้าที่
ได้อย่างปลอดภัย
หากกำหนดเป้าหมายเป็น Android 8.1 (API ระดับ 27) ขึ้นไป คุณจะกำหนด วิธีที่แอปตอบสนองต่อภัยคุกคามที่ทราบแล้วโดยใช้โปรแกรมในสิ่งต่อไปนี้ ด้วยวิธีต่อไปนี้
- คุณควบคุมได้ว่าจะให้แอปรายงานภัยคุกคามที่รู้จักไปยัง Safe หรือไม่ การท่องเว็บ
- คุณสามารถทำให้แอปทำงานบางอย่างโดยอัตโนมัติได้ เช่น จะกลับสู่ความปลอดภัย ทุกครั้งที่เจอ URL ที่จัดว่าเป็นภัยคุกคามที่รู้จัก
ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีออกคำสั่งให้อินสแตนซ์ของแอป
WebView
เพื่อกลับสู่ความปลอดภัยเสมอหลังจากพบ
ภัยคุกคาม:
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 ตำแหน่งทางภูมิศาสตร์ของ HTML5
สำหรับแอปที่กำหนดเป้าหมายเป็น Android 6.0 (API ระดับ 23) ขึ้นไป Geolocation API
รองรับเฉพาะในต้นทางที่ปลอดภัย เช่น HTTPS คำขอใดๆ ที่ส่งไปยัง
Geolocation API ในต้นทางที่ไม่ปลอดภัยจะถูกปฏิเสธโดยอัตโนมัติโดยไม่มีการเรียกใช้
เมธอด onGeolocationPermissionsShowPrompt()
ที่เกี่ยวข้อง
เลือกไม่ใช้การรวบรวมเมตริก
WebView
สามารถอัปโหลดข้อมูลการวินิจฉัยที่ไม่ระบุตัวตนไปยัง
Google เมื่อผู้ใช้ให้ความยินยอม มีการเก็บข้อมูลแยกตามแอป
สำหรับแต่ละแอปที่สร้างอินสแตนซ์ WebView
คุณสามารถเลือกไม่รับ
โดยการสร้างแท็กต่อไปนี้ในไฟล์ Manifest
องค์ประกอบ <application>
:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
ข้อมูลจะอัปโหลดจากแอปในกรณีที่ผู้ใช้ยินยอมและเท่านั้น แอปไม่อาจเลือกไม่ให้ความยินยอมได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเลือกไม่ใช้ข้อมูลการวินิจฉัย การรายงาน โปรดดูที่ความเป็นส่วนตัวของผู้ใช้ใน WebView การรายงาน
API การจัดการการสิ้นสุด
API การจัดการการสิ้นสุดจะจัดการกับกรณีที่กระบวนการแสดงผลสำหรับ
WebView
หายไป เนื่องจากระบบจะปิดโหมดแสดงภาพเพื่อเรียกคืน
หน่วยความจำที่จำเป็น หรือเนื่องจากกระบวนการของโหมดแสดงภาพขัดข้อง เมื่อใช้ API นี้ คุณ
ให้แอปของคุณดำเนินการต่อไป แม้ว่ากระบวนการของโหมดแสดงภาพจะหายไปก็ตาม
หากโหมดแสดงภาพขัดข้องในขณะที่โหลดหน้าเว็บบางหน้า
การโหลดหน้าเว็บเดียวกันนั้นอีกครั้งอาจทำให้ออบเจ็กต์ WebView
ใหม่
จะแสดงลักษณะการทำงานของ
ข้อขัดข้องในการแสดงผลเดียวกัน
ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีใช้ API นี้ใน
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 ความสำคัญของตัวแสดงผล
เมื่อ WebView
ออบเจ็กต์
ดำเนินการใน
หลายขั้นตอน คุณจึงมีความยืดหยุ่นในการจัดการแอป
คุณสามารถใช้ Renderer Importance API ซึ่งเปิดตัวไปใน
Android 8.0 หากต้องการตั้งค่านโยบายลำดับความสำคัญให้กับโหมดแสดงภาพที่กำหนดให้
ออบเจ็กต์ WebView
รายการ โดยเฉพาะอย่างยิ่ง คุณอาจต้องการส่วนหลักๆ
เพื่อดำเนินการต่อเมื่อโหมดแสดงภาพที่แสดง
วัตถุ WebView
รายการเสียชีวิต คุณอาจทำเช่นนี้ถ้า
คาดว่าจะไม่แสดงออบเจ็กต์ WebView
เป็นเวลานานเพื่อให้
ระบบจะเรียกคืนหน่วยความจำที่โหมดแสดงภาพใช้อยู่ได้
ข้อมูลโค้ดต่อไปนี้แสดงวิธีกำหนดลำดับความสำคัญให้กับโหมดแสดงภาพ
กระบวนการที่เชื่อมโยงกับออบเจ็กต์ WebView
ของแอป
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
ในข้อมูลโค้ดนี้ ลำดับความสำคัญของโหมดแสดงภาพจะเหมือนกับ หรือ
เป็นลำดับความสำคัญเริ่มต้นของแอป true
ลดลำดับความสำคัญของตัวแสดงผลเป็น
วันที่ RENDERER_PRIORITY_WAIVED
เมื่อออบเจ็กต์ WebView
ที่เชื่อมโยงไม่ปรากฏอีกต่อไป ในอีก
อาร์กิวเมนต์ true
แสดงว่าแอปของคุณไม่คํานึงถึง
ระบบจะทำให้กระบวนการแสดงผลทำงานอย่างต่อเนื่อง อันที่จริง ระดับความสำคัญที่ต่ำกว่า
ทำให้กระบวนการแสดงผล
หายไปจากหน่วยความจำ
เท่านั้น
โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ระบบจัดการกับสถานการณ์ที่มีหน่วยความจำต่ำได้ที่ กระบวนการและแอป วงจร