Пример просмотра webview shouldinterceptrequest

Мне нужно знать, как работает shouldinterceptrequest. Я не знаю, как создать и обработать этот метод для чтения и замены ссылки CSS. Спасибо!

Ответ 1

Ну, короткий ответ заключается в том, что он очень похож на shouldOverrideUrlLoading(WebView view, String url), как показано в учебнике WebView.

Чтобы начать работу, см. код ниже. Вы просто переопределяете метод shouldInterceptRequest(WebView view, String url) вашего WebViewClient. Очевидно, вам не нужно делать это inline, но ради компактности, что я сделал:

    WebView webview = (WebView) findViewById(R.id.webview);
    webview.setWebViewClient(new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
            if (url.contains(".css")) {
                return getCssWebResourceResponseFromAsset();
            } else {
                return super.shouldInterceptRequest(view, url);
            }
        }

        /**
         * Return WebResourceResponse with CSS markup from a String. 
         */
        @SuppressWarnings("deprecation")
        private WebResourceResponse getCssWebResourceResponseFromString() {
            return getUtf8EncodedCssWebResourceResponse(new StringBufferInputStream("body { background-color: #F781F3; }"));
        }

        /**
         * Return WebResourceResponse with CSS markup from an asset (e.g. "assets/style.css"). 
         */
        private WebResourceResponse getCssWebResourceResponseFromAsset() {
            try {
                return getUtf8EncodedCssWebResourceResponse(getAssets().open("style.css"));
            } catch (IOException e) {
                return null;
            }
        }

        /**
         * Return WebResourceResponse with CSS markup from a raw resource (e.g. "raw/style.css"). 
         */
        private WebResourceResponse getCssWebResourceResponseFromRawResource() {
            return getUtf8EncodedCssWebResourceResponse(getResources().openRawResource(R.raw.style));
        }

        private WebResourceResponse getUtf8EncodedCssWebResourceResponse(InputStream data) {
            return new WebResourceResponse("text/css", "UTF-8", data);
        }

    });

    webview.loadUrl("http://stackoverflow.com");

Поймайте загрузку файла css и верните свой собственный WebResourceResponse, содержащий данные, которые вы хотите загрузить вместо.

Обратите внимание, что для этого метода требуется уровень API 11.

Если вы хотите сделать что-то подобное для Android 2.x, вы можете попробовать использовать ранее упомянутый shouldOverrideUrlLoading(WebView view, String url), чтобы не загружать страницу, извлекать ее вручную, заменять ссылку на файл css своим собственным и наконец, вызовите loadData(String data, String mimeType, String encoding) (или loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)) в WebView, передав управляемое содержимое html как строку.

До:

Before

После:

After

Ответ 2

Это может быть интересно для вас. Он считывает файлы из определенных папок, и если запрос поступает с этим именем файла, он использует файл из папки с ресурсами, а не из веб-страницы.

    //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;
    }