WebView完整配置及正确使用,抠门式的内存管控
发布日期:2021-06-29 18:16:20
浏览次数:2
分类:技术文章
本文共 17653 字,大约阅读时间需要 58 分钟。
本文主要学习自网上各路大神后做的笔记、Demo,现整理至CSDN博客,主要有、、、 等大神。
1.要点
- 一个可视为浏览器的View
- 用于加载html页面及处理交互
- 重量级View,建议在代码中添加至布局内存角度
- 建议至于独立Activity且占满
2.使用
2.1布局文件
不在布局文件中直接引入使用,使用java代码添加WebView,便于管控其生命周期
2.2Java代码添加WebView
// LinearLayout mContentLayout; WebView mWebView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_h5); initToolbar(); initView();//初始化控件 initData(); } private void initView() { mContentLayout = findViewById(R.id.h5_content_layout); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); //代码中添加WebView mWebView = new WebView(this.getApplicationContext()); mWebView.setLayoutParams(params); mContentLayout.addView(mWebView); //配置WebView buildWebView(); }
2.3 控制生命周期,防止内存泄漏
// @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); } @SuppressLint("SetJavaScriptEnabled") @Override protected void onResume() { super.onResume(); mWebView.getSettings().setJavaScriptEnabled(true); } @Override protected void onPause() { dismissLoading(); mWebView.getSettings().setJavaScriptEnabled(false); super.onPause(); } @Override protected void onDestroy() { destoryWebView(); dismissLoading(); super.onDestroy(); } private void destoryWebView() { if (mWebView != null) { //加载空页面,并清理缓存、历史 mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebView.clearHistory(); mWebView.clearCache(true); //移除、释放 ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.destroy(); mWebView = null; } } private void dismissLoading() { }
2.4 重点:WebView 配置
private void buildWebView() { mWebView.setWebChromeClient(new WebChromeClient(){ @Override public void onReceivedTitle(WebView view, String title) { if (!TextUtils.isEmpty(title)){ if (title.length()<6){ mToolbarTitle.setText(title); }else if (title.length()>10){ mToolbarTitle.setTextSize(12f); title = title.substring(0,8); title = title + "..."; mToolbarTitle.setText(title); }else { mToolbarTitle.setTextSize(14f); mToolbarTitle.setText(title); } } } }); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); mWebView.setWebViewClient(new WebViewClient() { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(String.valueOf(request.getUrl()), request.getRequestHeaders()); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { showLoading(); } @Override public void onPageFinished(WebView view, String url) { dismissLoading(); } }); } else { mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { showLoading(); } @Override public void onPageFinished(WebView view, String url) { dismissLoading(); } }); } //设置 WebSettings webSettings = mWebView.getSettings(); //设置支持Javascript webSettings.setJavaScriptEnabled(true); //设置自适应 webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 //缩放 webSettings.setSupportZoom(true); //支持缩放,默认为true。是setBuiltInZoomControls(true)的前提。 webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false=不可缩放 webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件 webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //缓存模式如下: //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。 //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据. //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。 webSettings.setAllowFileAccess(true);//可以访问文件 webSettings.setDomStorageEnabled(true);// 开启DOM storage webSettings.setDatabaseEnabled(true);//开启database storage webSettings.setAppCacheEnabled(true);//开启Application Caches String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME; webSettings.setAppCachePath(cacheDirPath);//设置Caches缓存目录 //每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize() webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //通过JS打开新窗口 webSettings.setLoadsImagesAutomatically(true); //自动加载图片 webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式 }
3.其他细节代码
载入页面
private void loadH5(){ if (TextUtils.isEmpty(mUrlStr)){ return; } //先清理,后载入,减小内存占用 mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebView.clearHistory(); mWebView.clearCache(true); mWebView.loadUrl(mUrlStr); }
AndroidManifest.xml声明权限
AndroidManifest.xml声明H5Activity
res/values/style.xml
4.完整Activity代码
package com.cupster.webview;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Color;import android.net.http.SslError;import android.os.Build;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.annotation.RequiresApi;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.text.TextUtils;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.ViewGroup;import android.webkit.SslErrorHandler;import android.webkit.WebChromeClient;import android.webkit.WebResourceRequest;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import static android.view.KeyEvent.KEYCODE_BACK;public class H5Activity extends AppCompatActivity { private static final String TAG = "H5Activity"; private static final String APP_CACAHE_DIRNAME = "/didigoweb"; public static final String KEY_H5_URL = "H5_URL"; TextView mToolbarTitle; LinearLayout mContentLayout; WebView mWebView; String mUrlStr; boolean isCanScale = true; public static void open(Context context , String url){ Intent intent = new Intent(context , H5Activity.class); intent.putExtra(KEY_H5_URL ,url); context.startActivity(intent); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { View decorView = getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); getWindow().setStatusBarColor(Color.WHITE); } else { } setAndroidNativeLightStatusBar(this, true); setContentView(R.layout.activity_h5); initToolbar(); initView(); initData(); } @SuppressLint("SetJavaScriptEnabled") @Override protected void onResume() { super.onResume(); mWebView.getSettings().setJavaScriptEnabled(true); } @Override protected void onPause() { dismissLoading(); mWebView.getSettings().setJavaScriptEnabled(false); super.onPause(); } @Override protected void onDestroy() { destoryWebView(); dismissLoading(); super.onDestroy(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); } public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { finish(); return true; } return super.onKeyDown(keyCode, event); } private void initToolbar() { Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setTitle(""); toolbar.setBackgroundColor(getResources().getColor(R.color.white)); setSupportActionBar(toolbar); ImageView back = findViewById(R.id.toolbar_back_left); back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); ImageView scale = findViewById(R.id.toolbar_icon_msg); scale.setImageResource(R.mipmap.icon_web_scale); scale.setVisibility(View.VISIBLE); scale.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { isCanScale = !isCanScale; if (isCanScale){ ((ImageView)v).setImageResource(R.mipmap.icon_web_scalable); mWebView.getSettings().setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。 mWebView.getSettings().setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩 }else { ((ImageView)v).setImageResource(R.mipmap.icon_web_scale); mWebView.getSettings().setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。 mWebView.getSettings().setBuiltInZoomControls(false); //设置内置的缩放控件。若为false,则该WebView不可缩 } loadH5(); } }); mToolbarTitle = findViewById(R.id.toolbar_title); mToolbarTitle.setTextColor(getResources().getColor(R.color.text_black)); mToolbarTitle.setTextSize(16.0f); mToolbarTitle.setText("详情"); } private void initView() { mContentLayout = findViewById(R.id.h5_content_layout); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); mWebView = new WebView(this.getApplicationContext()); mWebView.setLayoutParams(params); mContentLayout.addView(mWebView); buildWebView(); } private void initData() { if (getIntent() == null){ finish(); return; } mUrlStr = getIntent().getStringExtra(KEY_H5_URL); if ( TextUtils.isEmpty(mUrlStr) || "null".equals(mUrlStr) ){ finish(); return; } loadH5(); } private void loadH5(){ if (TextUtils.isEmpty(mUrlStr)){ return; } mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebView.clearHistory(); mWebView.clearCache(true); mWebView.loadUrl(mUrlStr); } private void buildWebView() { mWebView.setWebChromeClient(new WebChromeClient(){ @Override public void onReceivedTitle(WebView view, String title) { if (!TextUtils.isEmpty(title)){ if (title.length()<6){ mToolbarTitle.setText(title); }else if (title.length()>10){ mToolbarTitle.setTextSize(12f); title = title.substring(0,8); title = title + "..."; mToolbarTitle.setText(title); }else { mToolbarTitle.setTextSize(14f); mToolbarTitle.setText(title); } } } }); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); mWebView.setWebViewClient(new WebViewClient() { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(String.valueOf(request.getUrl()), request.getRequestHeaders()); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { showLoading(); } @Override public void onPageFinished(WebView view, String url) { dismissLoading(); } }); } else { mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { showLoading(); } @Override public void onPageFinished(WebView view, String url) { dismissLoading(); } }); } //设置 WebSettings webSettings = mWebView.getSettings(); //设置支持Javascript webSettings.setJavaScriptEnabled(true); //设置自适应 webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 //缩放 webSettings.setSupportZoom(true); //支持缩放,默认为true。是setBuiltInZoomControls(true)的前提。 webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false=不可缩放 webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件 //其他细节操作 webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //缓存模式如下: //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。 //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据. //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。 webSettings.setAllowFileAccess(true);//可以访问文件 webSettings.setDomStorageEnabled(true);// 开启DOM storage webSettings.setDatabaseEnabled(true);//开启database storage webSettings.setAppCacheEnabled(true);//开启Application Caches String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME; webSettings.setAppCachePath(cacheDirPath);//设置Caches缓存目录 //每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize() webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //通过JS打开新窗口 webSettings.setLoadsImagesAutomatically(true); //自动加载图片 webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式 } private void showLoading(){ } // private void destoryWebView() { if (mWebView != null) { mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebView.clearHistory(); mWebView.clearCache(true); ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.destroy(); mWebView = null; } } private void dismissLoading() { } protected static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) { View decor = activity.getWindow().getDecorView(); if (dark) { decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else { decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); } }}
5.完整代码 ,copy即用
github:
感谢:
、、、 等大神
转载地址:https://cupster.blog.csdn.net/article/details/104289177 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月10日 23时56分14秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
面试笔试易错知识点Java篇八
2019-04-29
弹性事务框架ETF4J——面向Java微服务的交易最终一致性解决方案
2019-04-29
【Scala 教程】Scala 条件与循环语句
2019-04-29
【Scala 教程】Scala 集合类型
2019-04-29
JAVA 线程同步机制 synchronized
2019-04-29
MySQL 安装教程(无脑版)
2019-04-29
IDEA 怎么删除一个Module
2019-04-29
走进数据科学:最好是通过比网课更好的方法
2019-04-29
AI革命第一步:最容易被忽略但必不可少的物联网
2019-04-29
2020年开发运维工具清单:选择开发运维工具堆栈吧
2019-04-29
效率提升法则:高效人士不会去做的4件事
2019-04-29
8.PostgreSQL约束
2019-04-29
【技术分享】使用AES加密技术保障数据安全
2019-04-29
【应用实例】布线多?成本高?不可靠?泽耀方案没烦恼!
2019-04-29
数据可视化工具:Matplotlib绘图
2019-04-29
用Python写个超级小恐龙跑酷游戏,上班摸鱼我能玩一天
2019-04-29
闺蜜看我用Python画了一幅樱花图,吵着要我给他介绍程序员小哥哥
2019-04-29
【Python爬虫实战】知乎热榜数据采集,上班工作摸鱼两不误,知乎热门信息一网打尽
2019-04-29