WebView 객체 관리

Android는 API를 관리하는 데 도움이 되는 여러 API를 WebView 객체입니다.

이 페이지에서는 이러한 API를 사용하여 WebView를 사용하는 방법을 설명합니다. 객체를 더 효과적으로 사용하여 앱의 안정성과 보안을 개선할 수 있습니다.

버전 API

Android 7.0 (API 수준 24)부터 사용자는 WebView 객체에 웹 콘텐츠를 표시하기 위한 다양한 패키지 AndroidX.webkit 라이브러리에는 <ph type="x-smartling-placeholder">getCurrentWebViewPackage()</ph> 웹을 표시하는 패키지와 관련된 정보를 가져오는 메서드 만들 수 있습니다. 이 방법은 특정 언어에서만 발생하는 오류를 분석할 때 앱이 특정 패키지의 WebView의 구현입니다.

이 메서드를 사용하려면 다음 코드 스니펫에 표시된 로직을 추가합니다.

Kotlin

val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext)
Log.d("MY_APP_TAG", "WebView version: ${webViewPackageInfo.versionName}")

자바

PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext);
Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);
<ph type="x-smartling-placeholder">

Google 세이프 브라우징 서비스

사용자에게 더 안전한 브라우징 환경을 제공하려면 WebView 객체는 Google 세이프 브라우징 이렇게 하면 사용자가 안전하지 않을 가능성이 있는 웹사이트

EnableSafeBrowsing의 기본값은 true이지만 세이프 브라우징을 조건부로만 사용하거나 사용 중지합니다. Android 8.0 (API 수준 26) 이상은 setSafeBrowsingEnabled() 드림 개별 WebView 객체에 관해 세이프 브라우징을 전환합니다.

모든 WebView 객체에서 세이프 브라우징을 선택 해제하려는 경우 검사하려면 다음 <meta-data> 요소를 앱의 매니페스트 파일:

<ph type="x-smartling-placeholder">
<manifest>
    <application>
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="false" />
        ...
    </application>
</manifest>
드림 <ph type="x-smartling-placeholder">

프로그래매틱 작업 정의하기

WebView의 인스턴스가 Google에서 알려진 위협으로 분류했으며 기본적으로 WebView입니다. 사용자에게 알려진 위협에 대해 경고하는 전면 광고가 표시되는 경우 이 화면은 어쨌든 URL을 로드하거나 이전 페이지로 돌아가는 옵션을 사용할 수 있습니다. 있습니다.

Android 8.1 (API 수준 27) 이상을 타겟팅하는 경우 앱이 알려진 위협에 프로그래매틱 방식으로 대응하는 방법은 다음과 같습니다. 있습니다.

  • 앱에서 알려진 위협을 Safe에 보고할지 여부를 제어할 수 있습니다. 탐색을 탭합니다.
  • 앱이 특정 작업을 자동으로 수행하도록 할 수 있습니다. 문제가 되는 URL을 발견할 때마다 알려진 위협으로 분류되었습니다.
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">

다음 코드 스니펫은 앱의 인스턴스에 WebView: 알려진 보안 문제가 발생한 후 항상 안전한 상태로 위협:

MyWebActivity.java

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!")
            }
        })
    }
}

자바

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!");
                }
            }
        });
    }
}

MyWebViewClient.java

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()
        }
    }
}

자바

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();
        }
    }
}

HTML5 위치정보 API

Android 6.0 (API 수준 23) 이상을 타겟팅하는 앱의 경우 Geolocation API 안전한 출처(예: HTTPS)에서만 지원됩니다 비보안 출처의 Geolocation API가 호출 없이 자동으로 거부됩니다. 상응하는 onGeolocationPermissionsShowPrompt() 메서드를 호출합니다.

측정항목 수집 선택 해제

WebView은(는) 다음 위치에 익명의 진단 데이터를 업로드할 수 있습니다. 사용자가 동의한 경우 Google. 데이터는 앱별로 수집됩니다. WebView를 인스턴스화하는 각 앱에 적용됩니다. 이 기능을 선택 해제할 수 있습니다. 매니페스트의 <application> 요소:

<manifest>
    <application>
    ...
    <meta-data android:name="android.webkit.WebView.MetricsOptOut"
               android:value="true" />
    </application>
</manifest>

데이터는 사용자가 동의하고 그리고 앱이 선택 해제되지 않습니다. 진단 데이터 선택 해제에 대해 자세히 알아보기 자세한 내용은 WebView의 사용자 개인 정보 보호 기능 보고를 참조하세요.

종료 처리 API

종료 처리 API는 종료 시점에 대한 렌더기 프로세스가 WebView 객체가 사라집니다. 이는 시스템이 렌더러를 종료하여 회수하기 때문입니다. 렌더러 프로세스가 비정상 종료되므로 이 API를 사용하면 렌더기 프로세스가 사라져도 앱이 계속 실행되도록 해야 합니다.

<ph type="x-smartling-placeholder">

특정 웹페이지를 로드하는 동안 렌더러가 충돌을 일으켜 같은 페이지를 다시 로드하면 새 WebView 객체가 동일한 렌더링 비정상 종료 동작을 보입니다.

다음 코드 스니펫은 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
    }
}

자바

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 객체. 특히, 이 함수의 주요 부분을 앱의 UI 요소를 표시하는 렌더러가 WebView 객체가 종료됩니다. 예를 들어 WebView 객체를 오랫동안 표시하지 않을 것으로 예상되어 시스템에서 렌더러가 사용 중이던 메모리를 회수할 수 있습니다.

다음 코드 스니펫은 렌더기에 우선순위를 할당하는 방법을 보여줍니다. 앱의 WebView 객체와 연결된 프로세스:

Kotlin

val myWebView: WebView = ...
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)

자바

WebView myWebView;
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);

이 특정 스니펫에서 렌더기의 우선순위는 앱의 기본 우선순위입니다. true 인수는 렌더러의 우선순위를 RENDERER_PRIORITY_WAIVED 연결된 WebView 객체가 더 이상 표시되지 않을 때 기타 true 인수는 앱이 시스템은 렌더러 프로세스를 활성 상태로 유지합니다 실제로 이렇게 낮은 우선순위 수준은 렌더러 프로세스가 메모리 부족으로 종료될 가능성이 높습니다. 있습니다.

<ph type="x-smartling-placeholder">

시스템이 메모리 부족 상황을 처리하는 방법에 대해 자세히 알아보려면 다음을 참조하세요. 프로세스 및 앱 수명 주기를 참고하세요.