WebView의 HTTP 요청 가로 채기 및 재정의
내 응용 프로그램에 일부 사이트가 열리는 WebView가 있습니다 (항상 동일하며 내 페이지입니다). 사이트에는 원격 호스트에서 일부 이미지를로드하는 JS 코드가 있습니다.
이러한 이미지에 대한 요청을 (URL 패턴으로) 가로 채고 내 콘텐츠 (예 : 다른 이미지)를 반환하거나 내부 애플리케이션 논리에 따라 요청을 그대로두고 싶습니다.
그렇게 할 수 있습니까?
편집 : 질문의 현재 상태 ...
WebView
WebViewClient
(Axarydax에서 언급했듯이) 설정하는 기능이 있습니다. WebViewClient
두 가지 유용한 방법이있다
shouldOverrideUrlLoading
onLoadResource
shouldOverrideUrlLoading
페이지 상호 작용에 의해로드가 트리거되는 경우 (예 : 페이지의 링크를 클릭하면 WebView.loadURL ( "")이이 메소드를 트리거하지 않음) URL로드를 가로 챌 수 있습니다. false를 반환하여 URL 로딩을 취소 할 수도 있습니다. 이 접근 방식은 사용할 수 없습니다. 페이지 리소스로드를 가로 챌 수 없습니다 (그리고 가로 채야하는 이미지는 이러한 페이지 리소스 임).
onLoadResource
페이지 리소스 (및 이미지! thx에서 jessyjones까지)가로드 될 때마다 트리거되지만 취소 할 방법은 없습니다. 이 방법은 내 작업에도 적합하지 않습니다.
API 레벨 11이 필요한 것을 지원하는 것 같습니다. 을 참조하십시오 WebViewClient.shouldInterceptRequest()
.
이것을 시도해보십시오. 개인 위키와 같은 앱에서 사용했습니다.
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("foo://")) {
// magic
return true;
}
return false;
}
});
내가 아는 한 shouldOverrideUrlLoading은 이미지가 아니라 하이퍼 링크에 대해 호출됩니다. 적절한 방법은 다음과 같습니다.
@Override public void onLoadResource(WebView view, String url)
이 메서드는 웹뷰에 의해로드되는 모든 리소스 (이미지, 스타일 시트, 스크립트)에 대해 호출되지만 무효이기 때문에 해당 URL을 변경하고 로컬 리소스를로드하도록 대체하는 방법을 찾지 못했습니다.
내 앱에 사용하는 솔루션은 다음과 같습니다.
css / js / img anf 글꼴 파일이있는 여러 자산 폴더가 있습니다.
응용 프로그램은 모든 파일 이름을 가져와이 이름의 파일이 요청되었는지 확인합니다. 그렇다면 자산 폴더에서로드합니다.
//get list of files of specific asset folder
private ArrayList listAssetFiles(String path) {
List myArrayList = new ArrayList();
String [] list;
try {
list = getAssets().list(path);
for(String f1 : list){
myArrayList.add(f1);
}
} catch (IOException e) {
e.printStackTrace();
}
return (ArrayList) myArrayList;
}
//get mime type by url
public String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
if (extension.equals("js")) {
return "text/javascript";
}
else if (extension.equals("woff")) {
return "application/font-woff";
}
else if (extension.equals("woff2")) {
return "application/font-woff2";
}
else if (extension.equals("ttf")) {
return "application/x-font-ttf";
}
else if (extension.equals("eot")) {
return "application/vnd.ms-fontobject";
}
else if (extension.equals("svg")) {
return "image/svg+xml";
}
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
//return webresourceresponse
public WebResourceResponse loadFilesFromAssetFolder (String folder, String url) {
List myArrayList = listAssetFiles(folder);
for (Object str : myArrayList) {
if (url.contains((CharSequence) str)) {
try {
Log.i(TAG2, "File:" + str);
Log.i(TAG2, "MIME:" + getMimeType(url));
return new WebResourceResponse(getMimeType(url), "UTF-8", getAssets().open(String.valueOf(folder+"/" + str)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
//@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("NewApi")
@Override
public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
//Log.i(TAG2, "SHOULD OVERRIDE INIT");
//String url = webResourceRequest.getUrl().toString();
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
//I have some folders for files with the same extension
if (extension.equals("css") || extension.equals("js") || extension.equals("img")) {
return loadFilesFromAssetFolder(extension, url);
}
//more possible extensions for font folder
if (extension.equals("woff") || extension.equals("woff2") || extension.equals("ttf") || extension.equals("svg") || extension.equals("eot")) {
return loadFilesFromAssetFolder("font", url);
}
return null;
}
API 버전은 언급하지 않았지만 API 11부터 WebViewClient.shouldInterceptRequest 메서드가 있습니다.
이게 도움이 될까요?
궁극적 인 해결책은 루프백시 '비밀'포트에서 수신하는 간단한 http 서버를 포함하는 것입니다. 그런 다음 일치하는 이미지 src URL을 http : // localhost : 123 /.../ mypic.jpg 와 같이 대체 할 수 있습니다 .
This may helps:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
WebResourceResponse response = super.shouldInterceptRequest(view, request);
// load native js
if (url != null && url.contains(INJECTION_TOKEN/* scheme define */)) {
response = new WebResourceResponse(
"text/javascript",
"utf-8",
loadJsInputStream(url, JsCache.getJsFilePath(path) /* InputStream */));
}
return response;
}
참고URL : https://stackoverflow.com/questions/4780899/intercept-and-override-http-requests-from-webview
'Program Tip' 카테고리의 다른 글
SQL에서 UPDATE는 항상 DELETE + INSERT보다 빠릅니까? (0) | 2020.12.03 |
---|---|
여러 선택적 매개 변수를 C # 함수에 전달 (0) | 2020.12.03 |
목록 반복 중에 java.util.List에서 요소를 제거 할 때 ConcurrentModificationException이 발생합니까? (0) | 2020.12.03 |
알 수없는 유형 이름 'uint8_t', MinGW (0) | 2020.12.03 |
주어진 텍스트 파일에서 모든 공백을 제거하는 방법 (0) | 2020.12.03 |