Back

android - webview 的用法

发布时间: 2019-05-24 14:21:00

增加webview的办法,非常简单,向特定的activity xml 中添加:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NewWebviewActivity">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </WebView>

</android.support.constraint.ConstraintLayout>

activity中:

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        //mShouldDeepStatus = false;

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_webview);
        WebView webView = (WebView) findViewById(R.id.webView);

        //声明WebSettings子类

        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);    //排版适应屏幕
        settings.setLoadWithOverviewMode(true);                             // setUseWideViewPort方法设置webview推荐使用的窗口。setL
        settings.setUseWideViewPort(true);
        settings.setPluginState(WebSettings.PluginState.ON);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setAllowFileAccess(true);
        settings.setDefaultTextEncodingName("UTF-8");
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//        webView.setBackgroundColor(getResources().getColor(R.color.backGround));
        webView.setVisibility( View.VISIBLE);




        if(Build.VERSION.SDK_INT >= 21){
            settings.setMixedContentMode(0);
            webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        }else if(Build.VERSION.SDK_INT >= 19){
            webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        }else if(Build.VERSION.SDK_INT < 19){
            webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

        webView.setWebViewClient(new GenericWebViewClient(getApplicationContext().getCacheDir()));

        webView.setWebChromeClient(new WebChromeClient());
        webView.loadUrl("https://siwei.me");
    }

新建class: 

package com.wondercv;

import android.graphics.Bitmap;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;

public class GenericWebViewClient extends WebViewClient {

    public String TAG = this.getClass().getSimpleName();

    public GenericWebViewClient(File folder){
        this.cacheFolder = folder;
    }

    private File cacheFolder;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        Log.d(TAG, "onPageStarted, 触发的url是====" + url);
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        Log.d(TAG, "取消小菊花开始...");
        // 取消小菊花 放在这里才可以.   针对myorder  打开的时候小菊花不会消失。
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        Log.d(TAG, "shouldInterceptRequest, 触发的url是====" + url);
        if(url.contains("__webpack_hmr")) {
            Log.d(TAG, "return empty response on __webpack_hmr");
            return new WebResourceResponse(null,null, null);
        }

        if( shouldQueryFromCache(url)) {
            return queryFromCacheIfPossible(url);
        }

        return super.shouldInterceptRequest(view, url);
    }



    public boolean shouldQueryFromCache(String url) {

        // endsWith 方法貌似不支持   a | b 这样的表达式...只好这么写了 ...   Orz
        boolean result =  url.endsWith("png") ||
                url.endsWith("PNG") ||
                url.endsWith("jpg") ||
                url.endsWith("JPG") ||
                url.endsWith("jpeg") ||
                url.endsWith("JPEG") ||
                url.endsWith("css") ||
                url.endsWith("css.map") ||
                url.endsWith("js") ||
                url.endsWith("js.map")
                ;

        return result;
    }

    /**
     * 核心方法. 根据url, 向远程发起请求, 并保存文件到本地.
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public WebResourceResponse queryFromCacheIfPossible(final String url) {
        Log.d(TAG, "== in queryFromCacheIfPossible, url: "+ url);
        Log.d(TAG, "== cacheFolder : "+ cacheFolder);

        String webResourceLocalFileName = getWebResourceLocalFileName(url);
        File webResourceCacheFile = new File( cacheFolder, webResourceLocalFileName);

        if(webResourceCacheFile.exists()){
            Log.d(TAG, "== hit the cache: " + webResourceLocalFileName);
            try{
                FileInputStream fileInputStream = new FileInputStream(new File(cacheFolder, webResourceLocalFileName));
                return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", fileInputStream);
            }catch (IOException e){
                e.printStackTrace();
                return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", null);
            }
        }else{
            Log.d(TAG, "== NOT hit the cache: " + webResourceLocalFileName);
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(url)
                    .build();
            try {
                Response response = okHttpClient.newCall(request).execute();

                writeHttpResponseToFile(url, response);
                Log.d(TAG, "== mime : " + getMimeTypeBySuffix(url));
                // 这段代码可以让图片正常显示!
                //   js:  doing...
                FileInputStream fileInputStream = new FileInputStream(new File(cacheFolder, webResourceLocalFileName));

                return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", fileInputStream);

            }catch (IOException e){
                Log.e(TAG, "== got IOException");
                e.printStackTrace();
                return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", null);
            }
        }

    }

    public String getWebResourceLocalFileName(String url){
        String[] temp = url.split("/");
        String fileName = temp[temp.length - 1];
        return fileName;
    }

    public String writeHttpResponseToFile(String url, Response response){
        String fileName = getWebResourceLocalFileName(url);
        Log.d(TAG, "== in writeHttpResponseToFile");
        // TODO Write file ...
        File file = new File(cacheFolder, fileName);

        try{
            BufferedSink bufferedSink = Okio.buffer(Okio.sink(file));
            bufferedSink.writeAll(response.body().source());
            bufferedSink.close();
        }catch(Exception e){
            Log.e(TAG, "== got error in writeHttpResponseToFile");
            e.printStackTrace();
        }
        return fileName;

    }

    public String getMimeTypeBySuffix(String url){
        String result = "";
        if(url.endsWith("png") || url.endsWith("PNG")){
            result = "image/png";
        }else if (url.endsWith("jpg") || url.endsWith("JPG")
                || url.endsWith("jpeg") || url.endsWith("JPEG")){
            result = "image/jpg";
        }else if (url.endsWith("css") || url.endsWith("css.map")){
            result = "text/css";
        }else if (url.endsWith("js") ||url.endsWith(".js.map") ){
            result = "application/javascript";
        }else{
            result = "text/plain";
        }
        return result;
    }
}

Back