Android中WebView性能优化

2017-09-01  本文已影响0人  奕晴天

前言

WebView首次启动优化-常用资源预加载

例子
webview.loadUrl("http://ip.cn/");//加载http://ip.cn/
webview.setWebViewClient(new WebViewClient(){
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
       view.loadUrl(url);
       return true;
  }

  //api21以下
  @Override
  public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
       if(url.contains("logo.gif")){
          InputStream is = null;
          try {
                 is = getApplicationContext().getAssets().open("images/index.jpg");
          } catch (IOException e) {
                 e.printStackTrace();
          }
          WebResourceResponse response = new WebResourceResponse("image/jpg","utf-8",is);
                    return response;
     }
          return super.shouldInterceptRequest(view, url);
   }

  //api21以上
  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  @Override
  public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
      if (request.getUrl().toString().contains("logo.gif")){
          InputStream is = null;
          try {
                is = getApplicationContext().getAssets().open("images/index.jpg");
          } catch (IOException e) {
                e.printStackTrace();
          }
          WebResourceResponse response = new WebResourceResponse("image/jpg","utf-8",is);
              return response;
       }
              return super.shouldInterceptRequest(view, request);
  }
});

图片.png 图片.png

常用JS本地化及延迟加载

WebView二次启动优化

WebView的缓存模式
//优先使用缓存:
WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
// 不使用缓存: 
WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
浏览器缓存机制-前端开发人员负责(静态文件缓存)
 //代表本地缓存,且从发起请求算起,接下来500s,如果有该资源请求都不会进行HTTP请求,而是读取本地的缓存
 Cache-Control:max-age=500
Dom Storage
//通过webSettings.setDomStorageEnabled(true);//生效。
webSettings.setDomStorageEnabled(true)
IndexDB
//通过JS执行开发进行使能
webSettings.setJavaScriptEnabled(true);
缓存总结
  1. 存储静态资源文件(JS、CSS、图片资源)- 采用浏览器缓存机制。
  2. 存储临时、简单的数据 - 采用Dom Storage缓存机制。
  3. 存储结构复杂、数据量大的数据 - 采用IndexDB缓存机制。

WebView防止内存泄漏

解决方案
activity_webview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</RelativeLayout>
WebViewActivity.java
public class WebViewActivity extends BaseActivity {

    private RelativeLayout rl_layout;
    private WebView webview;
    private WebSettings webSettings;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);
        initWebView();
    }

    private void initWebView(){
        //避免WebView内存泄露
        rl_layout = (RelativeLayout) findViewById(R.id.rl_layout);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        webview = new WebView(getApplicationContext());
        webview.setLayoutParams(params);
        rl_layout.addView(webview);

        webSettings = webview.getSettings();
        webSettings.setUseWideViewPort(true);//将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true);// 缩放至屏幕的大小

        webSettings.setSupportZoom(true);//支持缩放,默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(true);//支持缩放,默认为true。是下面那个的前提。
        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
        webSettings.setAllowFileAccess(true); //设置可以访问文件
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
        webSettings.setDomStorageEnabled(true);// 开启 DOM storage API 功能
        webSettings.setAppCacheEnabled(true);// 开启 Application Caches 功能

        //优先使用缓存:
        // WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        // 缓存模式如下:
        // LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
        // LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
        // LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
        // LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
        // 不使用缓存: WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        //根据以上两种模式,建议缓存策略为:
        // 判断是否有网络,有的话,使用LOAD_DEFAULT,
        // 无网络时,使用LOAD_CACHE_ELSE_NETWORK。
        webview.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            //api21以下
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                if(url.contains("logo.gif")){
                    InputStream is = null;
                    try {
                        is = getApplicationContext().getAssets().open("images/index.jpg");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    WebResourceResponse response = new WebResourceResponse("image/jpg","utf-8",is);
                    return response;
                }
                return super.shouldInterceptRequest(view, url);
            }

            //api21以上
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                if (request.getUrl().toString().contains("logo.gif")){
                    InputStream is = null;
                    try {
                        is = getApplicationContext().getAssets().open("images/index.jpg");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    WebResourceResponse response = new WebResourceResponse("image/jpg","utf-8",is);
                    return response;
                }
                return super.shouldInterceptRequest(view, request);
            }

        });

        webview.loadUrl("http://ip.cn/");
    }

    @Override
    protected void onResume() {
        super.onResume();
        webSettings.setJavaScriptEnabled(true);
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        webSettings.setJavaScriptEnabled(false);
    }

    @Override
    protected void onDestroy() {
        //避免WebView内存泄露
        if (webview != null){
            webview.loadDataWithBaseURL(null,"","tex/html","utf-8",null);
            webview.clearHistory();
            ((ViewGroup)webview.getParent()).removeView(webview);
            webview.destroy();
            webview = null;
        }
        super.onDestroy();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()){
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
上一篇下一篇

猜你喜欢

热点阅读