android webkit 如何管理内存,WebView完整配置及正确使用,抠门式的内存管控

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

1.要点

一个可视为浏览器的View

用于加载html页面及处理交互

重量级View,建议在代码中添加至布局内存角度

建议至于独立Activity且占满

2.使用

2.1布局文件

不在布局文件中直接引入使用,使用java代码添加WebView,便于管控其生命周期

< LinearLayoutxmlns:android= "http://schemas.android.com/apk/res/android"

android:layout_width= "match_parent"

android:layout_height= "match_parent"

android:orientation= "vertical">

< include

layout= "@layout/app_toolbar_base"

/>

< LinearLayout

android:id= "@+id/h5_content_layout"

android:orientation= "vertical"

android:layout_width= "match_parent"

android:layout_height= "match_parent"

android:paddingTop= "8dp"

>

LinearLayout>

LinearLayout>

2.2Java代码添加WebView

//

LinearLayout mContentLayout;

WebView mWebView;

@ Override

protectedvoidonCreate( @Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_h5);

initToolbar;

initView; //初始化控件

initData;

}

privatevoidinitView( ){

mContentLayout = findViewById(R.id.h5_content_layout);

LinearLayout.LayoutParams params= newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

//代码中添加WebView

mWebView = newWebView( this.getApplicationContext);

mWebView.setLayoutParams( params);

mContentLayout.addView(mWebView);

//配置WebView

buildWebView;

}

2.3 控制生命周期,防止内存泄漏

//

@Override

protectedvoidonNewIntent(Intent intent){

super.onNewIntent(intent);

setIntent(intent);

}

@SuppressLint( "SetJavaEnabled")

@Override

protectedvoidonResume{

super.onResume;

mWebView.getSettings.setJavaEnabled( true);

}

@Override

protectedvoidonPause{

dismissLoading;

mWebView.getSettings.setJavaEnabled( false);

super.onPause;

}

@Override

protectedvoidonDestroy{

destoryWebView;

dismissLoading;

super.onDestroy;

}

privatevoiddestoryWebView{

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;

}

}

privatevoiddismissLoading{

}

2.4 重点:WebView 配置

privatevoidbuildWebView{

mWebView.setWebChromeClient( newWebChromeClient{

@Override

publicvoidonReceivedTitle(WebView view, String title){

if(!TextUtils.isEmpty(title)){

if(title.length< 6){

mToolbarTitle.setText(title);

} elseif(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( newWebViewClient {

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

@Override

publicbooleanshouldOverrideUrlLoading(WebView view, WebResourceRequest request){

view.loadUrl(String.valueOf(request.getUrl), request.getRequestHeaders);

returntrue;

}

@Override

publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){

handler.proceed;

}

@Override

publicvoidonPageStarted(WebView view, String url, Bitmap favicon){

showLoading;

}

@Override

publicvoidonPageFinished(WebView view, String url){

dismissLoading;

}

});

} else{

mWebView.setWebViewClient( newWebViewClient {

@Override

publicbooleanshouldOverrideUrlLoading(WebView view, String url){

view.loadUrl(url);

returntrue;

}

@Override

publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){

handler.proceed;

}

@Override

publicvoidonPageStarted(WebView view, String url, Bitmap favicon){

showLoading;

}

@Override

publicvoidonPageFinished(WebView view, String url){

dismissLoading;

}

});

}

//设置

WebSettings webSettings = mWebView.getSettings;

//设置支持Java

webSettings.setJavaEnabled( 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.setJavaCanOpenWindowsAutomatically( true); //通过JS打开新窗口

webSettings.setLoadsImagesAutomatically( true); //自动加载图片

webSettings.setDefaultTextEncodingName( "utf-8"); //设置编码格式

}

3.其他细节代码

载入页面

privatevoidloadH5( ){

if(TextUtils.isEmpty(mUrlStr)){

return;

}

//先清理,后载入,减小内存占用

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

mWebView.clearHistory;

mWebView.clearCache( true);

mWebView.loadUrl(mUrlStr);

}

AndroidManifest.xml声明权限

< uses-permissionandroid:name= "android.permission.INTERNET"/>

AndroidManifest.xml声明H5Activity

< activity

android:name= ".H5Activity"

android:screenOrientation= "portrait"/>

res/values/style.xml

< stylename= "AppTheme"parent= "Theme.AppCompat.Light.NoActionBar">

< itemname= "colorPrimary">@color/colorPrimary item>

< itemname= "colorPrimaryDark">@color/colorPrimaryDark item>

< itemname= "colorAccent">@color/colorAccent item>

style>

4.完整Activity代码

packagecom.cupster.webview;

importandroid.annotation.SuppressLint;

importandroid.app.Activity;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.graphics.Bitmap;

importandroid.graphics.Color;

importandroid.net.http.SslError;

importandroid.os.Build;

importandroid.os.Bundle;

importandroid.support.annotation.Nullable;

importandroid.support.annotation.RequiresApi;

importandroid.support.v7.app.AppCompatActivity;

importandroid.support.v7.widget.Toolbar;

importandroid.text.TextUtils;

importandroid.util.Log;

importandroid.view.KeyEvent;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.webkit.SslErrorHandler;

importandroid.webkit.WebChromeClient;

importandroid.webkit.WebResourceRequest;

importandroid.webkit.WebSettings;

importandroid.webkit.WebView;

importandroid.webkit.WebViewClient;

importandroid.widget.ImageView;

importandroid.widget.LinearLayout;

importandroid.widget.TextView;

importstaticandroid.view.KeyEvent.KEYCODE_BACK;

publicclassH5ActivityextendsAppCompatActivity{

privatestaticfinalString TAG = "H5Activity";

privatestaticfinalString APP_CACAHE_DIRNAME = "/didigoweb";

publicstaticfinalString KEY_H5_URL = "H5_URL";

TextView mToolbarTitle;

LinearLayout mContentLayout;

WebView mWebView;

String mUrlStr;

booleanisCanScale = true;

publicstaticvoidopen(Context context , String url){

Intent intent = newIntent(context , H5Activity.class);

intent.putExtra(KEY_H5_URL ,url);

context.startActivity(intent);

}

@Override

protectedvoidonCreate(@Nullable Bundle savedInstanceState){

super.onCreate(savedInstanceState);

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

View decorView = getWindow.getDecorView;

intoption = 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( "SetJavaEnabled")

@Override

protectedvoidonResume{

super.onResume;

mWebView.getSettings.setJavaEnabled( true);

}

@Override

protectedvoidonPause{

dismissLoading;

mWebView.getSettings.setJavaEnabled( false);

super.onPause;

}

@Override

protectedvoidonDestroy{

destoryWebView;

dismissLoading;

super.onDestroy;

}

@Override

protectedvoidonNewIntent(Intent intent){

super.onNewIntent(intent);

setIntent(intent);

}

publicbooleanonKeyDown( intkeyCode, KeyEvent event){

if((keyCode == KEYCODE_BACK) && mWebView.canGoBack) {

finish;

returntrue;

}

returnsuper.onKeyDown(keyCode, event);

}

privatevoidinitToolbar{

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( newView.OnClickListener {

@Override

publicvoidonClick(View v){

finish;

}

});

ImageView scale = findViewById(R.id.toolbar_icon_msg);

scale.setImageResource(R.mipmap.icon_web_scale);

scale.setVisibility(View.VISIBLE);

scale.setOnClickListener( newView.OnClickListener {

@Override

publicvoidonClick(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( "详情");

}

privatevoidinitView{

mContentLayout = findViewById(R.id.h5_content_layout);

LinearLayout.LayoutParams params = newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

mWebView = newWebView( this.getApplicationContext);

mWebView.setLayoutParams(params);

mContentLayout.addView(mWebView);

buildWebView;

}

privatevoidinitData{

if(getIntent == null){

finish;

return;

}

mUrlStr = getIntent.getStringExtra(KEY_H5_URL);

if( TextUtils.isEmpty(mUrlStr) || "null".equals(mUrlStr) ){

finish;

return;

}

loadH5;

}

privatevoidloadH5{

if(TextUtils.isEmpty(mUrlStr)){

return;

}

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

mWebView.clearHistory;

mWebView.clearCache( true);

mWebView.loadUrl(mUrlStr);

}

privatevoidbuildWebView{

mWebView.setWebChromeClient( newWebChromeClient{

@Override

publicvoidonReceivedTitle(WebView view, String title){

if(!TextUtils.isEmpty(title)){

if(title.length< 6){

mToolbarTitle.setText(title);

} elseif(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( newWebViewClient {

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

@Override

publicbooleanshouldOverrideUrlLoading(WebView view, WebResourceRequest request){

view.loadUrl(String.valueOf(request.getUrl), request.getRequestHeaders);

returntrue;

}

@Override

publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){

handler.proceed;

}

@Override

publicvoidonPageStarted(WebView view, String url, Bitmap favicon){

showLoading;

}

@Override

publicvoidonPageFinished(WebView view, String url){

dismissLoading;

}

});

} else{

mWebView.setWebViewClient( newWebViewClient {

@Override

publicbooleanshouldOverrideUrlLoading(WebView view, String url){

view.loadUrl(url);

returntrue;

}

@Override

publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){

handler.proceed;

}

@Override

publicvoidonPageStarted(WebView view, String url, Bitmap favicon){

showLoading;

}

@Override

publicvoidonPageFinished(WebView view, String url){

dismissLoading;

}

});

}

//设置

WebSettings webSettings = mWebView.getSettings;

//设置支持Java

webSettings.setJavaEnabled( 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.setJavaCanOpenWindowsAutomatically( true); //通过JS打开新窗口

webSettings.setLoadsImagesAutomatically( true); //自动加载图片

webSettings.setDefaultTextEncodingName( "utf-8"); //设置编码格式

}

privatevoidshowLoading{

}

//

privatevoiddestoryWebView{

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;

}

}

privatevoiddismissLoading{

}

protectedstaticvoidsetAndroidNativeLightStatusBar(Activity activity, booleandark){

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://github.com/Cupster/OneDayOneView/tree/master/webview

感谢:

鸿洋_、郭霖、Carson_Ho、aqi00 等大神

原文作者:Cupster

原文链接:https://blog.csdn.net/Cupster/article/details/104289177

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值