WebView完整配置及正确使用,抠门式的内存管控
发布日期:2021-06-29 18:16:20 浏览次数:2 分类:技术文章

本文共 17653 字,大约阅读时间需要 58 分钟。

本文主要学习自网上各路大神后做的笔记、Demo,现整理至CSDN博客,主要有、、、 等大神。


1.要点

  1. 一个可视为浏览器的View
  2. 用于加载html页面及处理交互
  3. 重量级View,建议在代码中添加至布局内存角度
  4. 建议至于独立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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:解决Android Studio gradle_jcenter()下载慢,使用maven阿里源
下一篇:解决AS3.x无法新建Module:Project needs to be converted to androidx.* dependencies

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月10日 23时56分14秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章