광고주는 HTML, 자바스크립트, 웹 기반 앱 등의 CSS—앱에 정적으로 컴파일하는 것을 사용하기 더 효율적입니다
인앱 콘텐츠는 인터넷 액세스가 필요하지 않으며 사용자의 대역폭을 사용하지도 않습니다. 만약
콘텐츠가 WebView
만을 대상으로 합니다. 즉,
기본 앱과의 통신에 달려 있으므로 사용자는 실수로
웹 브라우저에서 로드합니다.
하지만 인앱 콘텐츠에는 몇 가지 단점이 있습니다. 웹 기반 콘텐츠 업데이트 새 앱 업데이트를 제공해야 하며 기기에 있는 콘텐츠와 앱의 콘텐츠 사이에 콘텐츠가 얼마나 차이가 나는지를 사용자가 오래된 앱 버전을 사용 중입니다.
WebViewAssetLoader 클래스의 생성자
WebViewAssetLoader
은(는)
앱에서 인앱 콘텐츠를 로드할 수 있는
WebView
객체. 이 클래스는
있습니다.
- same-origin과의 호환성을 위해 HTTP(S) URL로 콘텐츠 로드 정책을 참조하세요.
- JavaScript, CSS, 이미지, iframe과 같은 하위 리소스 로드
기본 활동 파일에 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
인스턴스를 필요에 맞게 구성해야 합니다. 이
다음 섹션에 예시가 있습니다
인앱 애셋 및 리소스 만들기
WebViewAssetLoader
가
PathHandler
인스턴스를 사용하여 지정된 리소스 경로에 해당하는 리소스를 로드합니다. 비록
앱에서 필요에 따라 리소스를 검색하기 위해 이 인터페이스를 구현할 수 있지만,
Webkit 라이브러리 번들
AssetsPathHandler
드림
및
ResourcesPathHandler
각각 Android 애셋과 리소스를 로드하는 데 사용됩니다.
시작하려면 앱의 애셋과 리소스를 만드세요. 일반적으로 다음 사항이 적용됩니다.
- HTML, JavaScript, CSS와 같은 텍스트 파일은 애셋에 속합니다.
- 이미지 및 기타 바이너리 파일은 리소스에 속합니다.
프로젝트에 텍스트 기반 웹 파일을 추가하려면 다음 단계를 따르세요.
- Android 스튜디오에서 app > src > 기본 폴더 새로 만들기 > 디렉터리로 이동합니다. <ph type="x-smartling-placeholder">
- 폴더 이름을 'assets'로 지정합니다.
- assets 폴더를 마우스 오른쪽 버튼으로 클릭한 다음 새로 만들기 > File을 참고하세요.
index.html
를 입력하고 Return 키를 누르거나 Enter 키. <ph type="x-smartling-placeholder"> - 이전 단계를 반복하여
stylesheet.css
- 다음 두 코드에서 콘텐츠로 만든 빈 파일을 채웁니다. 샘플입니다.
```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;
}
```
프로젝트에 이미지 기반 웹 파일을 추가하려면 다음 단계를 따르세요.
지금 바로
Android_symbol_green_RGB.png
드림 업로드할 수 있습니다파일 이름을
android_robot.png
로 바꿉니다.파일을 프로젝트의
main/res/drawable
디렉터리로 수동으로 이동합니다. 하드 드라이브에 다시 연결합니다.
그림 4에는 추가한 이미지와 위의 코드 샘플에서 가져온 텍스트가 나와 있습니다. 앱에 렌더링됩니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.앱을 완료하려면 다음 단계를 따르세요.
핸들러를 등록하고 다음을 추가하여
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));
다음 코드를
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/
및 URLfile://android_res/
개AssetsHandler
및ResourcesHandler
클래스는 삽입형 교체에 적합합니다. -
MIXED_CONTENT_ALWAYS_ALLOW
이 설정은 일반적으로 필요하지 않으며 앱의 보안을 약화시킵니다. 인앱 콘텐츠는 동일한 방식(HTTP 또는 HTTPS: 웹사이트의 리소스로 사용하고MIXED_CONTENT_COMPATIBILITY_MODE
드림 또는MIXED_CONTENT_NEVER_ALLOW
, 적절하게 수정할 수 있습니다.