인앱 콘텐츠 로드

광고주는 HTML, 자바스크립트, 웹 기반 앱 등의 CSS—앱에 정적으로 컴파일하는 것을 사용하기 더 효율적입니다

인앱 콘텐츠는 인터넷 액세스가 필요하지 않으며 사용자의 대역폭을 사용하지도 않습니다. 만약 콘텐츠가 WebView만을 대상으로 합니다. 즉, 기본 앱과의 통신에 달려 있으므로 사용자는 실수로 웹 브라우저에서 로드합니다.

하지만 인앱 콘텐츠에는 몇 가지 단점이 있습니다. 웹 기반 콘텐츠 업데이트 새 앱 업데이트를 제공해야 하며 기기에 있는 콘텐츠와 앱의 콘텐츠 사이에 콘텐츠가 얼마나 차이가 나는지를 사용자가 오래된 앱 버전을 사용 중입니다.

WebViewAssetLoader 클래스의 생성자

WebViewAssetLoader은(는) 앱에서 인앱 콘텐츠를 로드할 수 있는 WebView 객체. 이 클래스는 있습니다.

기본 활동 파일에 WebViewAssetLoader를 포함합니다. 다음은 애셋 폴더에서 간단한 웹 콘텐츠를 로드하는 예:

Kotlin

private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
    @RequiresApi(21)
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }

    // To support API < 21.
    override fun shouldInterceptRequest(
        view: WebView,
        url: String
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(Uri.parse(url))
    }
}

자바

private static class LocalContentWebViewClient extends WebViewClientCompat {

    private final WebViewAssetLoader mAssetLoader;

    LocalContentWebViewClient(WebViewAssetLoader assetLoader) {
        mAssetLoader = assetLoader;
    }

    @Override
    @RequiresApi(21)
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     WebResourceRequest request) {
        return mAssetLoader.shouldInterceptRequest(request.getUrl());
    }

    @Override
    @SuppressWarnings("deprecation") // To support API < 21.
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     String url) {
        return mAssetLoader.shouldInterceptRequest(Uri.parse(url));
    }
}

앱에서는 WebViewAssetLoader 인스턴스를 필요에 맞게 구성해야 합니다. 이 다음 섹션에 예시가 있습니다

인앱 애셋 및 리소스 만들기

WebViewAssetLoaderPathHandler 인스턴스를 사용하여 지정된 리소스 경로에 해당하는 리소스를 로드합니다. 비록 앱에서 필요에 따라 리소스를 검색하기 위해 이 인터페이스를 구현할 수 있지만, Webkit 라이브러리 번들 AssetsPathHandler 드림 및 ResourcesPathHandler 각각 Android 애셋과 리소스를 로드하는 데 사용됩니다.

시작하려면 앱의 애셋과 리소스를 만드세요. 일반적으로 다음 사항이 적용됩니다.

  • HTML, JavaScript, CSS와 같은 텍스트 파일은 애셋에 속합니다.
  • 이미지 및 기타 바이너리 파일은 리소스에 속합니다.

프로젝트에 텍스트 기반 웹 파일을 추가하려면 다음 단계를 따르세요.

  1. Android 스튜디오에서 app > src > 기본 폴더 새로 만들기 > 디렉터리로 이동합니다. <ph type="x-smartling-placeholder">
    </ph> Android 스튜디오 디렉터리 만들기 메뉴를 보여주는 이미지 <ph type="x-smartling-placeholder">
    </ph> 그림 1. 다음에 대한 애셋 폴더 만들기 살펴보겠습니다
  2. 폴더 이름을 'assets'로 지정합니다.
    애셋 폴더를 보여주는 이미지
    그림 2. 애셋 폴더의 이름을 지정합니다.
  3. assets 폴더를 마우스 오른쪽 버튼으로 클릭한 다음 새로 만들기 > File을 참고하세요. index.html를 입력하고 Return 키를 누르거나 Enter 키. <ph type="x-smartling-placeholder">
  4. 이전 단계를 반복하여 stylesheet.css
  5. 다음 두 코드에서 콘텐츠로 만든 빈 파일을 채웁니다. 샘플입니다.
```html
<!-- index.html content -->

<html>
  <head>
    <!-- Tip: Use relative URLs when referring to other in-app content to give
              your app code the flexibility to change the scheme or domain as
              necessary. -->
    <link rel="stylesheet" href="/assets/stylesheet.css">
  </head>
  <body>
    <p>This file is loaded from in-app content.</p>
    <p><img src="/res/drawable/android_robot.png" alt="Android robot" width="100"></p>
  </body>
</html>
```

```css
<!-- stylesheet.css content -->

body {
  background-color: lightblue;
}
```

프로젝트에 이미지 기반 웹 파일을 추가하려면 다음 단계를 따르세요.

  1. 지금 바로 Android_symbol_green_RGB.png 드림 업로드할 수 있습니다

  2. 파일 이름을 android_robot.png로 바꿉니다.

  3. 파일을 프로젝트의 main/res/drawable 디렉터리로 수동으로 이동합니다. 하드 드라이브에 다시 연결합니다.

그림 4에는 추가한 이미지와 위의 코드 샘플에서 가져온 텍스트가 나와 있습니다. 앱에 렌더링됩니다.

앱 렌더링 출력을 보여주는 이미지
그림 4. 인앱 HTML 파일 및 이미지 파일 앱에 렌더링됩니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

앱을 완료하려면 다음 단계를 따르세요.

  1. 핸들러를 등록하고 다음을 추가하여 AssetLoader를 구성합니다. onCreate() 메서드에 다음 코드를 추가하세요.

    Kotlin

    val assetLoader = WebViewAssetLoader.Builder()
                           .addPathHandler("/assets/", AssetsPathHandler(this))
                           .addPathHandler("/res/", ResourcesPathHandler(this))
                           .build()
    webView.webViewClient = LocalContentWebViewClient(assetLoader)
    

    자바

    final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
             .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
             .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this))
             .build();
    mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
    
  2. 다음 코드를 onCreate() 메서드에 추가하여 콘텐츠를 로드합니다.

    Kotlin

    webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
    

    자바

    mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
    

인앱 콘텐츠와 웹사이트의 리소스를 함께 사용하기

앱에서 인앱 콘텐츠와 인터넷(예: 웹사이트의 CSS에 의해 스타일이 지정된 인앱 HTML 페이지) WebViewAssetLoader는 이 사용 사례를 지원합니다. 등록된 기기 중 아무 것도 등록하지 않은 경우 인스턴스 PathHandler개가 지정된 경로의 리소스를 찾을 수 있습니다. WebView에 해당합니다. 다시 인터넷에서 콘텐츠를 로드하는 것으로 여겨집니다. 인앱 콘텐츠와 /assets/ 또는 /resources/: 인앱 리소스의 경우 Cloud Shell의 리소스를 확인할 수 있습니다.

Kotlin

val assetLoader = WebViewAssetLoader.Builder()
                        .setDomain("example.com") // Replace this with your website's domain.
                        .addPathHandler("/assets/", AssetsPathHandler(this))
                        .build()

webView.webViewClient = LocalContentWebViewClient(assetLoader)
val inAppHtmlUrl = "https://example.com/assets/index.html"
webView.loadUrl(inAppHtmlUrl)
val websiteUrl = "https://example.com/website/data.json"

// JavaScript code to fetch() content from the same origin.
val jsCode = "fetch('$websiteUrl')" +
        ".then(resp => resp.json())" +
        ".then(data => console.log(data));"

webView.evaluateJavascript(jsCode, null)

자바

final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
           .setDomain("example.com") // Replace this with your website's domain.
           .addPathHandler("/assets/", new AssetsPathHandler(this))
           .build();

mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
String inAppHtmlUrl = "https://example.com/assets/index.html";
mWebView.loadUrl(inAppHtmlUrl);
String websiteUrl = "https://example.com/website/data.json";

// JavaScript code to fetch() content from the same origin.
String jsCode = "fetch('" + websiteUrl + "')" +
      ".then(resp => resp.json())" +
      ".then(data => console.log(data));";

mWebView.evaluateJavascript(jsCode, null);

WebView 데모 보기: GitHub 웹 호스팅 JSON 데이터를 가져오는 인앱 HTML 페이지의 예입니다.

기본 URL을 사용한 로드 데이터

앱이 HTML 페이지만 로드하면 되고 가로채기를 할 필요가 없는 경우 하위 리소스가 있으므로 loadDataWithBaseURL()님, 이 경우 앱 확장 소재가 필요하지 않습니다. 다음 코드와 같이 사용할 수 있습니다. 샘플:

Kotlin

val html = "<html><body><p>Hello world</p></body></html>"
val baseUrl = "https://example.com/"

webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)

자바

String html = "<html><body><p>Hello world</p></body></html>";
String baseUrl = "https://example.com/";

mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);

인수 값을 신중하게 선택합니다. 다음을 고려하세요.

  • baseUrl: HTML 콘텐츠가 로드되는 URL입니다. 이 이름은 HTTP(S) URL입니다.
  • data: 표시하려는 HTML 콘텐츠입니다(문자열).
  • mimeType: 일반적으로 text/html로 설정해야 합니다.
  • encoding: baseUrl이 HTTP(S) URL인 경우에는 사용되지 않으므로 다음과 같을 수 있습니다. null로 설정합니다.
  • historyUrl: baseUrl와 동일한 값으로 설정됩니다.

HTTP(S) URL을 baseUrl로 사용하는 것이 좋습니다. 이렇게 하면 앱이 동일 출처 정책을 준수하도록 해야 합니다.

콘텐츠에 적합한 baseUrl을(를) 찾을 수 없어 이를 사용하려는 경우 loadData(), 콘텐츠를 인코딩해야 하며 백분율 인코딩 또는 Base64 인코딩을 사용합니다. Base64 인코딩을 선택하고 Android API를 사용하여 다음 코드 샘플에서와 같이 프로그래매틱 방식으로 사용합니다.

Kotlin

val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING)

webView.loadData(encodedHtml, mimeType, "base64")

자바

String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING);

mWebView.loadData(encodedHtml, mimeType, "base64");

피해야 할 사항

인앱 콘텐츠를 로드하는 방법에는 여러 가지가 있지만 대항하여:

  • file:// URL과 data: URL은 불투명한 출처로 간주됩니다. 즉, 웹 서버와 같은 강력한 웹 API를 사용할 수 없으며 fetch() 또는 XMLHttpRequest loadData()는 내부적으로 data: URL을 사용하므로 대신 WebViewAssetLoader 또는 loadDataWithBaseURL()를 사용하세요.
  • 하지만 WebSettings.setAllowFileAccessFromFileURLs() 드림 및 WebSettings.setAllowUniversalAccessFromFileURLs() file:// URL 관련 문제를 해결할 수 있으므로 true에 전달합니다. 그렇게 하면 앱이 파일 기반에 취약해지기 때문입니다. 있습니다. 모든 API 수준에서 명시적으로 false로 설정하는 것이 좋습니다. 제공합니다
  • 같은 이유로 file://android_assets/ 및 URL file://android_res/AssetsHandlerResourcesHandler 클래스는 삽입형 교체에 적합합니다.
  • MIXED_CONTENT_ALWAYS_ALLOW 이 설정은 일반적으로 필요하지 않으며 앱의 보안을 약화시킵니다. 인앱 콘텐츠는 동일한 방식(HTTP 또는 HTTPS: 웹사이트의 리소스로 사용하고 MIXED_CONTENT_COMPATIBILITY_MODE 드림 또는 MIXED_CONTENT_NEVER_ALLOW, 적절하게 수정할 수 있습니다.