美文网首页
WebView预加载

WebView预加载

作者: wyj先生 | 来源:发表于2019-11-15 14:54 被阅读0次

    - 场景:

    单Activity中有很多Fragment,Fragment中使用webview;如果不进行优化每次重新进入Fragmeng都会看到webview加载url的一个漫长过程; 避免这种情况,我的思路是:提前实例化webview,用一个容器将这些实例装起来,用到的时候取出来addView(WebView到布局中);

    - 先贴出使用代码,后边补充预加载相关类:

    在MainActivity中初始化启动预加载:

    private void  preWebView(){

        for (String url: Urls.getUrls()) {

            if (url!=null){

                WebViewTool.getInstance().putWebView(url,new MyWebView(mContext,url));

            }

        }

    }

    Fragmetn中使用webview;

    public class WaterAnalysisFragment extends BaseFragment {

        private String url = Api.IP + "wateranalysis";

        @BindView(R.id.ll)

        LinearLayout ll;

        MyWebView webView;

        @Override

        protected int getLayoutId() {

            return R.layout.water_frament_analysis;

        }

        public static WaterAnalysisFragment newInstance() {

            return new WaterAnalysisFragment();

        }

        @Override

        protected void initEventAndData() {

            webView = WebViewTool.getInstance().getWebView(url);

            if (webView != null) {

                int childCount = ll.getChildCount(); 

                if (childCount > 0) {

                } else {

                    ll.addView(webView);

                }

            } else {

                webView = new MyWebView(mContext, url);

                webView.loadWebUrl(url);

                ll.addView(webView);

            }

        }

        /**

        * 如果放在 onDestroyView中销毁容易报错:Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

        * 快速返回activity在快速重复进入就会报错,因为onDestroyView 有一定延迟;=按返回家不一定销毁

        */

        @Override

        public void onPause() {

            if (webView != null) { 

                WebViewTool.getInstance().removeWebView(webView);

            }

            super.onPause();

        }

    }

    ---------------------ok,这样就实现了加载webview秒开的效果-------------------------------------------------

    补充预加载相关类:

    1:需要预加载的url地址

    public class Urls {

        private static List<String> urls; // 需要预加载的url集合

        static {

            urls = new ArrayList<>();

            urls.add("https://www.baidu.com/");

            urls.add("http://192.168.0.96:8888/onlinemonitoring");

            urls.add("http://192.168.0.96:8888/wateranalysis");

        }

        public static List<String> getUrls() {

            return urls;

        }

    }

    2:给webview加个进度条;

    public class MyWebView extends WebView {

      private Context mContext;

      private ProgressBar progressbar;  //顶部进度条

      private int progressHeight = 8;  //进度条的高度,默认8px

      MyWebChromeClient WebChromeClient;

      public MyWebView(Context context, String url) {

          super(context);

          mContext = context;

          if (url!=null){

            loadWebUrl(url);

          }

          setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));

          initWebViewSettings();

      }

      /**在xml布局文件中定义的时候调用*/

      public MyWebView(Context context, AttributeSet attrs, String url) {

          super(context, attrs);

          mContext = context;

          if (url!=null){

            loadWebUrl(url);

          }

          initWebViewSettings();

          setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));

      }

      private void initWebViewSettings(){

          WebSettings settings = getSettings();

          settings.setJavaScriptEnabled(true);//设置WebView是否允许执行JavaScript脚本,默认false,不允许。

          settings.setJavaScriptCanOpenWindowsAutomatically(true);

          settings.setBuiltInZoomControls(false);

          settings.setDomStorageEnabled(true);

          settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

          settings.setDatabaseEnabled(true);

          settings.setAppCacheEnabled(true);

          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

          }

          //创建进度条

          progressbar = new ProgressBar(mContext, null, android.R.attr.progressBarStyleHorizontal);

    //    proDialog=new ProgressBar(mContext, null, android.R.attr.progressBarStyleLarge);

          //设置加载进度条的高度

          progressbar.setLayoutParams(new LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, progressHeight, 0, 0));

          Drawable drawable = mContext.getResources().getDrawable(R.drawable.progress_bar_states);

          progressbar.setProgressDrawable(drawable);

          // 将proDialog设置到容器的中央位置

          //添加进度到WebView

          addView(progressbar);

          WebChromeClient= new MyWebChromeClient(getContext(),progressbar);

          setWebChromeClient(WebChromeClient);

      }

      /**加载远程网页

        * @param webUrl - 远程网页链接地址:比如http://m.baidu.com/*/

      public void loadWebUrl(String webUrl){

          this.loadUrl(webUrl);

      }

      /**加载本地assets目录下的网页

        * @param localUrl - assets目录下的路径:比如www/login.html*/

      public void loadLocalUrl(final String localUrl){

          this.loadUrl("file:///android_asset/"+localUrl);

      }

      ...

    }

    3:管理类:

    public class WebViewTool {

        private Map<String, MyWebView> webViews = new HashMap<>();

        private static class LazyHolder {

            private static final WebViewTool INSTANCE = new WebViewTool();

        }

        private WebViewTool() {

        }

        public static final WebViewTool getInstance() {

            return LazyHolder.INSTANCE;

        }

        public  Map<String, MyWebView> getWebViews() {

            return webViews;

        }

        public void putWebView(String url, MyWebView webView) {

            webViews.put(url, webView);

        }

        public MyWebView getWebView(String url){

            MyWebView webView=webViews.get(url);

            if (webView!=null){

                return webView;

            }

            return null;

        }

        public void  destoryAll(){

            for(Map.Entry<String, MyWebView> entry: webViews.entrySet())

            {

                String key=entry.getKey();

                MyWebView webView= entry.getValue();

                webView.stopLoading();

                webViews.remove(key);

            }

        }

        public  void removeWebView(MyWebView webView) {

          // webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);

            //webView.clearHistory();

            if (webView!=null){

                ((ViewGroup) webView.getParent()).removeView(webView);

            }

        }

    }

    4:其他优化,慢慢做去,时间太忙,刚刚实现的顺带做了个笔记;

    相关文章

      网友评论

          本文标题:WebView预加载

          本文链接:https://www.haomeiwen.com/subject/kocsictx.html