GVKun编程网logo

Android:如何在 webview 内容中制作双倍宽度和双倍高度的文本

10

想了解Android:如何在webview内容中制作双倍宽度和双倍高度的文本的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于AndroidWebView系列文章1-关于WebView基

想了解Android:如何在 webview 内容中制作双倍宽度和双倍高度的文本的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于Android WebView 系列文章 1 - 关于 WebView 基本使用介绍、android webview 设置字体大小后 webview高度不会缩小、Android WebView从WebViewClient到Activity通信、Android WebView开发(三):WebView性能优化的新知识。

本文目录一览:

Android:如何在 webview 内容中制作双倍宽度和双倍高度的文本

Android:如何在 webview 内容中制作双倍宽度和双倍高度的文本

afaik 您只能设置字体大小(通过 WebSettings 类)... WebView 不是那么有弹性,并且没有提供用于管理/样式化打印文本的详细选项。为此,CSS 是为之而生的。最终最好在网页端的 Javascript 中实现此功能或以明文形式下载数据,修改适当的行(添加 CSS)并使用 loadData(...)

WebView 方法

Android WebView 系列文章 1 - 关于 WebView 基本使用介绍

Android WebView 系列文章 1 - 关于 WebView 基本使用介绍

关于 WebView 基本使用介绍
目录介绍
0. 关于 WebView 的目录结构图
1. 关于 WebView 的使用优点
2.WebView 最简单的使用方法
3.WebView 的常用方法

    * 3.1 WebView 的回退与前进与刷新
    * 3.2 WebView 的状态
    * 3.3 清除缓存数据

4.WebView 常用类的介绍

    * 4.1 WebSettings 类
    * 4.2 WebViewClient 类
    * 4.3 WebChromeClient 类

5.WebView 注意事项

    * 5.1 动态创建 WebView 使用上下文为全局上下文
    * 5.2 Activity 销毁的时候,销毁 WebView

 

 

1. 关于 WebView 的使用优点

    * 可以直接显示和渲染 web 页面,直接显示网页
    * webview 可以直接用 html 文件(网络上或本地 assets 中)作布局
    * 和 JavaScript 交互调用


2.WebView 最简单的使用方法

    * 布局

<WebView
    android:id="@+id/wv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
注意添加权限:
<uses-permission android:name="android.permission.INTERNET"/>

    * 在 activity 中最简单的使用

webview = (WebView) findViewById(R.id.webView1);
webview.loadUrl ("http://www.baidu.com/");                    // 加载 web 资源
webView.loadUrl ("file:///android_asset/example.html");       // 加载本地资源
这个时候发现一个问题,启动应用后,自动的打开了系统内置的浏览器,解决这个问题需要为 webview 设置 WebViewClient,并重写方法:
webview.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                // 返回值是 true 的时候控制去 WebView 打开,为 false 调用系统浏览器或第三方浏览器
                return true;
            }
 // 还可以重写其他的方法
});


3.WebView 的常用方法

    * 3.1 WebView 的回退与前进与刷新
    *
        * WebView 前进用到的时候可能不多,但是回退这个功能相当有用。当加载网页的时候,我们点击了几层链接之后,点击返回键,突然间就退出应用或者直接销毁了当前组件,相信这种交互不是用户需要的,因为有可能用户只是想回退到上一层级页面。
        * 关于方法介绍与使用


// 判断是否有可以回退,可以返回 true
webView.canGoBack();
// 返回上一层级
webView.goBack();
// 判断是否可以前进,可以返回 true
webView.canGoForward();
// 进入上一层级
webView.goForward();
// 刷新
webView.reload();

// 改写物理按键 —— 返回的逻辑 这个很重要
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK) {
        if(wv.canGoBack()) {
            wv.goBack ();// 返回上一页面
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}


    * 3.2 WebView 的状态

// 激活 WebView 为活跃状态,能正常执行网页的响应
webView.onResume() ;

// 当页面被失去焦点被切换到后台不可见状态,需要执行 onPause// 通过 onPause 动作通知内核暂停所有的动作,比如 DOM 的解析、plugin 的执行、JavaScript 执行。
webView.onPause();

// 当应用程序 (存在 webview) 被切换到后台时,这个方法不仅仅针对当前的 webview 而是全局的全应用程序的 webview// 它会暂停所有 webview 的 layout,parsing,javascripttimer。降低 CPU 功耗。
webView.pauseTimers()
// 恢复 pauseTimers 状态
webView.resumeTimers();

// 销毁 Webview// 在关闭了 Activity 时,如果 Webview 的音乐或视频,还在播放。就必须销毁 Webview// 但是注意:webview 调用 destory 时,webview 仍绑定在 Activity 上 // 这是由于自定义 webview 构建时传入了该 Activity 的 context 对象 // 因此需要先从父容器中移除 webview, 然后再销毁 webview:
rootLayout.removeView(webView);
webView.destroy();

    * 3.3 清除缓存数据

// 清除网页访问留下的缓存
// 由于内核缓存是全局的因此这个方法不仅仅针对 webview 而是针对整个应用程序.
Webview.clearCache(true);

// 清除当前 webview 访问的历史记录 // 只会 webview 访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory();

// 这个 api 仅仅清除自动完成填充的表单数据,并不会清除 WebView 存储到本地的数据
Webview.clearFormData();


4.WebView 常用类的介绍

    * 4.1 WebSettings 类
    *
        * 主要的作用对 WebView 进行配置和管理


// 声明 WebSettings 子类
WebSettings webSettings = webView.getSettings();

// 注意:这个很重要   如果访问的页面中要与 Javascript 交互,则 webview 必须设置支持 Javascript
webSettings.setJavaScriptEnabled(true);

// 支持插件
webSettings.setPluginsEnabled(true);

// 设置自适应屏幕,两者合用
webSettings.setUseWideViewPort (true); // 将图片调整到适合 webview 的大小
webSettings.setLoadWithOverviewMode (true); // 缩放至屏幕的大小

// 缩放操作
webSettings.setSupportZoom (true); // 支持缩放,默认为 true。是下面那个的前提。
webSettings.setBuiltInZoomControls (true); // 设置内置的缩放控件。若为 false,则该 WebView 不可缩放
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");// 设置编码格式

    *
        * 设置 WebView 缓存

 

    *
        * 当加载 html 页面时,WebView 会在 /data/data/ 包名目录下生成 database 与 cache 两个文件夹
        * 请求的 URL 记录保存在 WebViewCache.db,而 URL 的内容是保存在 WebViewCache 文件夹下
        * 是否启用缓存:


// 优先使用缓存:
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);

webSettings.setDomStorageEnabled (true); // 开启 DOM storage API 功能
webSettings.setDatabaseEnabled (true);  // 开启 database storage API 功能
webSettings.setAppCacheEnabled (true);// 开启 Application Caches 功能

String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME;
webSettings.setAppCachePath (cacheDirPath); // 设置  Application Caches 缓存目录

    * 4.2 WebViewClient 类
    *
        * 主要的作用是处理各种通知和请求事件
        * shouldOverrideUrlLoading () 方法


shouldOverrideUrlLoading () 方法,使得打开网页时不调用系统浏览器, 而是在本 WebView 中显示
webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
});

    *
        * onPageStarted()


作用:开始载入页面调用的,我们可以设定一个 loading 的页面,告诉用户程序在等待网络响应。
webView.setWebViewClient(new WebViewClient(){
    @Override
    public void  onPageStarted(WebView view, String url, Bitmap favicon) {
        // 设定加载开始的操作
    }
});

    *
        * onPageFinished()


作用:在页面加载结束时调用。我们可以关闭 loading 条,切换程序动作。
webView.setWebViewClient(new WebViewClient(){
    @Override
    public void onPageFinished(WebView view, String url) {
        // 设定加载结束的操作
    }
});

    *
        * onLoadResource()


作用:在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean onLoadResource(WebView view, String url) {
        // 设定加载资源的操作
    }
});

    *
        * onReceivedError()


作用:加载页面的服务器出现错误时(如 404)调用。
App 里面使用 webview 控件的时候遇到了诸如 404 这类的错误的时候,若也显示浏览器里面的那种错误提示页面就显得很丑陋了,那么这个时候我们的 app 就需要加载一个本地的错误提示页面,即 webview 如何加载一个本地的页面

// 步骤 1:写一个 html 文件(error_handle.html),用于出错时展示给用户看的提示页面
// 步骤 2:将该 html 文件放置到代码根目录的 assets 文件夹下
// 步骤 3:复写 WebViewClient 的 onRecievedError 方法
// 该方法传回了错误码,根据错误类型可以进行不同的错误分类处理
webView.setWebViewClient(new WebViewClient(){
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
        switch(errorCode){
            case HttpStatus.SC_NOT_FOUND:
                view.loadUrl("file:///android_assets/error_handle.html");
                break;
        }
    }
});

    *
        * onReceivedSslError()


作用:处理 https 请求
webView 默认是不处理 https 请求的,页面显示空白,需要进行如下设置:

webView.setWebViewClient(new WebViewClient() {   
    @Override   
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {   
        handler.proceed ();    // 表示等待证书响应
        //handler.cancel ();      // 表示挂起连接,为默认方式
        //handler.handleMessage (null);    // 可做其他处理
    }   
});   

    * 4.3 WebChromeClient 类
    *
        * 主要的作用是辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等
        * onProgressChanged()


作用:获得网页的加载进度并显示
webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        if (newProgress < 100) {
            String progress = newProgress + "%";
            progress.setText(progress);
        }
    }
});

    *
        * onReceivedTitle()


作用:获取 Web 页中的标题
每个网页的页面都有一个标题
webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onReceivedTitle(WebView view, String title) {
        titleview.setText(title);
    }
}


5.WebView 注意事项

    * 5.1 动态创建 WebView 使用上下文为全局上下文

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mWebView = new WebView(getApplicationContext());
mWebView.setLayoutParams(params);
mLayout.addView(mWebView);

    * 5.2 Activity 销毁的时候,销毁 WebView

在 Activity 销毁( WebView )的时候,先让 WebView 加载 null 内容,然后移除 WebView,再销毁 WebView,最后置空。
@Override
protected void onDestroy() {
    if (mWebView != null) {
        mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
        mWebView.clearHistory();

        ((ViewGroup) mWebView.getParent()).removeView(mWebView);
        mWebView.destroy();
        mWebView = null;
    }
    super.onDestroy();
}

 

 

 

 

 

 

android webview 设置字体大小后 webview高度不会缩小

android webview 设置字体大小后 webview高度不会缩小

webview的高度是wrap_content ,在4.2和4.3的机器上,字体反复动态设置大小后(setting.setDefaultFontSize(size);),webview高度总保持在最大字体的时候。在字体缩小时,webview的高度不会自动降低,   在4.4的机器上则会自动适应。   不知道各位大侠有什么好的思路。 万分感谢!

Android WebView从WebViewClient到Activity通信

Android WebView从WebViewClient到Activity通信

我有一个简单的helloworld应用程序.我试图告诉活动用户单击了“ Cnn.com”

    WebViewClient wc = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view,String url) {
            if (url.equals("http://cnn.com/")) {
                //TELL ACTIVITY CNN WAS CLICKED
                return true;
            } else {
                return false;

            }
        }

    };

    mWebView.setWebViewClient(wc);

我该怎么做.

(我来自C#.NET背景)

最佳答案
public class YourActivity extends Activity{

    // bla bla bla

    // the code you already have
    WebViewClient wc = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view,String url) {
            if (url.equals("http://cnn.com/")) {
                YourActivity.this.tellMe();
                return true;
            } else {
                return false;

            }
        }

    };

    // this is the method to 'tell' the activity that someone clicked the link
    public void tellMe(){
        // in this case I just raise a toast.
        // but you can do whatever you want here ;)
        Toast.makeText(YourActivity.this,"eyy!! somebody clicked the cnn link",1).show();
    }
}

Android WebView开发(三):WebView性能优化

Android WebView开发(三):WebView性能优化

一、Android WebView开发(一):基础应用
二、Android WebView开发(二):WebView与Native交互
三、Android WebView开发(三):WebView性能优化
四、Android WebView开发(四):WebView独立进程解决方案
五、Android WebView开发(五):自定义WebView工具栏


附GitHub源码:WebViewExplore


WebView性能优化方案:

1、WebView预初始化:

为了减少WebView的性能损耗,我们可以在合适时机提前创建好WebView,并存入缓存池,当页面需要显示内容时,直接从缓存池获取创建好的WebView,根据性能数据显示,WebView预创建可以减少首屏渲染时间200ms+。

Image

以新闻落地页为例,当用户进入新闻列表页时,我们会创建第一个WebView,当用户进入新闻落地页后,会从缓存池中取出来渲染H5页面,为了不影响页面的加载速度,同时保证下次进入落地页缓存池中仍然有可用的WebView组件,我们会在每次页面加载完成(pageFinish)或者back退出落地页的时机,去触发预创建WebView的逻辑。

由于WebView的初始化需要和context进行绑定,若想实现预创建的逻辑,需要保证context的一致性,常规做法我们考虑可以用fragment来实现承载H5页面的容器,这样context可以用外层的activity实例,但Fragment本身的切换流畅度存在一定问题,并且这样做限定了WebView预创建适用的场景。为此,我们找到了一种更加完美的替代方案,即:MutableContextwrapper新的context包装类,允许外部修改它的baseContext,并且所有Contextwrapper调用的方法都会代理到baseContext来执行

下面是一段预创建WebView的代码:


/**
     * 创建WebView实例
     * 用了applicationContext
     */
    @DebugTrace
    public void prepareNewWebView() {
        if (mCachedWebViewStack.size() < CACHED_WEBVIEW_MAX_NUM) {
            mCachedWebViewStack.push(new WebView(new MutableContextwrapper(getAppContext())));
        }
    }
    /**
     * 从缓存池中获取合适的WebView
     * 
     * @param context activity context
     * @return WebView
     */
    private WebView acquireWebViewInternal(Context context) {
        // 为空,直接返回新实例
        if (mCachedWebViewStack == null || mCachedWebViewStack.isEmpty()) {
            return new WebView(context);
        }
        WebView webView = mCachedWebViewStack.pop();
        // webView不为空,则开始使用预创建的WebView,并且替换Context
        MutableContextwrapper contextwrapper = (MutableContextwrapper) webView.getContext();
        contextwrapper.setBaseContext(context);
        return webView;
    }

2、关联的Native组件懒加载:

WebView初始化完成,可以立刻loadUrl,无需等待框架onCreate或者OnResume结束。另外WebView初始完成后到页面首页绘制完成之间,尽量减少UI线程的其他操作,繁忙的UI线程会拖慢WebView.loadUrl的速度。

具体到我们新闻落地页场景,由于我们的落地页包含两部分,WebView+Native评论组件,正常流程会在WebView初始化结束后,开始评论组件的初始化及评论数据的获取。由于此时评论的初始化仍处在onCreate的UI消息处理中,会严重延迟内核加载主文档的逻辑。考虑到用户进入落地页的时候,评论组件对用户来说并不可见,所以将评论组件的初始化延迟到页面的pageFinish时或首屏渲染完成时。

3、离线缓存:

WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//开启DOM缓存,关闭的话H5自身的一些操作是无效的
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
settings.setJavaScriptEnabled(true);

这边我们通过setCacheMode方法来设置WebView的缓存策略,WebSettings.LOAD_DEFAULT是默认的缓存策略,它在缓存可获取并且没有过期的情况下加载缓存,否则通过网络获取资源。这样的话可以减少页面的网络请求次数,那我们如何在离线的情况下也能打开页面呢,这里我们在加载页面的时候可以通过判断网络状态,在无网络的情况下更改webview的缓存策略

ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if(info.isAvailable())
{
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);
}else 
{
    settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//不使用网络,只加载缓存
}

这样我们就可以使我们的混合应用在没有网络的情况下也能使用一部分的功能,不至于什么都显示不了了,当然如果我们将缓存做的更好一些,在网络好的时候,比如说在WIFI状态下,去后台加载一些网页缓存起来,这样处理的话,即使在无网络情况下第一次打开某些页面的时候,也能将该页面显示出来。
当然缓存资源后随之会带来一个问题,那就是资源无法及时更新,WebSettings.LOAD_DEFAULT中的页面中的缓存版本好像不是很起作用,所以我们这边可能需要自己做一个缓存版本控制。这个缓存版本控制可以放在APP版本更新中。

if (upgrade.cacheControl > cacheControl)
{
    webView.clearCache(true);//删除DOM缓存
    VersionUtils.clearCache(mContext.getCacheDir());//删除APP缓存
    try
    {
        mContext.deleteDatabase("webview.db");//删除数据库缓存
        mContext.deleteDatabase("webviewCache.db");
    }
    catch (Exception e)
    {
    }
}

4、资源预(异步)加载:

1、通过shouldInterceptRequest(预)异步加载:

有时候一个页面资源比较多,图片,CSS,js比较多,还引用了JQuery这种庞然巨兽,从加载到页面渲染完成需要比较长的时间,解决方案就是可以按照一定的策略和时机,提前从CDN中请求部分落地页html缓存到本地,或者可以把html,css,js,image等资源预置在客户端本地,并和服务端协商好前端的版本控制和增量更新策略,如此一来Webview就可以先快速加载本地缓存页面资源,加载完成后,返回给WebView。剩下的就只需要拉取那些需要更新的增量资源即可。这样可以提升加载速度也能减少服务器压力。重写WebClient类中的 shouldInterceptRequest 【运行在子线程】方法,再将这个类设置给WebView。

        /**
         * 【实现预加载】
         * 有时候一个页面资源比较多,图片,CSS,js比较多,还引用了JQuery这种庞然巨兽,
         * 从加载到页面渲染完成需要比较长的时间,有一个解决方案是将这些资源打包进APK里面,
         * 然后当页面加载这些资源的时候让它从本地获取,这样可以提升加载速度也能减少服务器压力。
         */
        @Nullable
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view,WebResourceRequest request) {
            if (request == null) {
                return null;
            }
            String url = request.getUrl().toString();
            Log.d(TAG,"shouldInterceptRequest---> " + url);
            return getWebResourceResponse(url);
        }

        protected WebResourceResponse getWebResourceResponse(String url) {
            //此处[tag]等需要跟服务端协商好,再处理
            if (url.contains("[tag]")) {
                try {
                    String localPath = url.replaceFirst("^http.*[tag]\\]","");
                    InputStream is = getContext().getAssets().open(localPath);
                    Log.d(TAG,"shouldInterceptRequest: localPath " + localPath);
                    String mimeType = "text/javascript";
                    if (localPath.endsWith("css")) {
                        mimeType = "text/css";
                    }
                    return new WebResourceResponse(mimeType,"UTF-8",is);
                } catch (IOException e) {
                    e.printstacktrace();
                    return null;
                }
            } else {
                return null;
            }
        }

以常用的图片加载来说,此方案在满足图片渲染速度的同时,解耦了客户端和前端代码,客户端充当server角色,对图片进行请求和缓存控制,保证前端和客户端可以共用图片缓存。

2、H5页面拉取优化:

而针对这些需要拉取的增量资源,可以对它们进行webpack+gzip数据压缩和CDN加速处理,以提升拉取速度。并且在建立网络连接时,可以让前端请求的域名和客户端API接口域名一致,以减少DNS解析时间
最后,对于H5页面来说,图片资源的拉取是最为耗时的,一个比较好的解决方案就是先加载并展示非图片内容,延迟这些图片的加载,以提升用户体验。WebView有一个setBlockNetworkImage(boolean)方法,该方法的作用是是否屏蔽图片的加载。可以利用这个方法来实现图片的延迟加载:在onPageStarted时屏蔽图片加载,在onPageFinished时开启图片加载。

5、内存泄露:

首先针对WebView内存泄漏的问题,可用AS的Profiler来进行检测:

Android 如何用profiler检查内存泄漏【这里需要注意一点的是,点击垃圾回收按钮,手动gc时,需要多点几次,要不然不一定会进行正常的垃圾回收】。

另外之前自己曾多次尝试检测WebView内存泄漏,但是"遗憾"是发现并不会发生内存泄漏。试了下多台手机都没有发生。后来查了下相关文章【Android-WebView还会存在内存泄漏吗?】,了解到WebView内存泄漏其实只是早期内核版本的一个漏洞,现早已修复。所以包括5.0以上的大部分设备不会产生所谓的内存泄漏,低版本 Android 系统(Android 5以上)上搭载的 Chromium 内核一般来说也不会太旧,所以出现内存泄漏的概率应该是比较小的。如果仍需要兼容这很小的一部分机型,可以采用如下的这种两种方式:

1、避免在xml布局文件中直接嵌套webview控件,而是采用addview的方式new一个webview并加载到布局中,上下文变量使用applicationContext:

webView = new WebView(getApplicationContext());
webView.getSettings().setJavaScriptEnabled(true);
framelayout.addView(webView);
webView.loadUrl(url);

2、当activity生命周期结束时及时销毁/释放资源:

webview引起的内存泄漏主要是因为org.chromium.android_webview.AwContents 类中注册了component callbacks,但是未正常反注册而导致的。

org.chromium.android_webview.AwContents 类中有这两个方法 onAttachedToWindow 和 onDetachedFromWindow;系统会在attach和detach处进行注册和反注册component callback;
在onDetachedFromWindow() 方法的第一行中:

if (isDestroyed()) return;, 

如果 isDestroyed() 返回 true 的话,那么后续的逻辑就不能正常走到,所以就不会执行unregister的操作;我们的activity退出的时候,都会主动调用 WebView.destroy() 方法,这会导致 isDestroyed() 返回 true;destroy()的执行时间又在onDetachedFromWindow之前,所以就会导致不能正常进行unregister()。
然后解决方法就是:让onDetachedFromWindow先走,在主动调用destroy()之前,把webview从它的parent上面移除掉。

ViewParent parent = mWebView.getParent();
if (parent != null) {
    ((ViewGroup) parent).removeView(mWebView);
}

mWebView.destroy();

完整的activity的onDestroy()方法:如:

    @Override
    protected void onDestroy() {
        if (mWebView != null) {
            mWebView.destroy();

            ViewParent parent = mWebView.getParent();
            if (parent != null) {
                ((ViewGroup) parent).removeView(mWebView);
            }
            mWebView.stopLoading();
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            mWebView.getSettings().setJavaScriptEnabled(false);
            mWebView.clearHistory();
            mWebView.clearView();
            mWebView.removeAllViews();
            mWebView.destroy();
        }
        super.onDestroy();
    }

3、WebView独立进程解决方案:

解决WebView的内存泄漏及OOM的另一种解决方案是通过开辟独立进程来实现,具体可参考:

WebView独立进程解决方案

参考:

WebView内存泄漏--解决方法小结 - 简书

今日头条品质优化 - 图文详情页秒开实践

WebView性能、体验分析与优化 - 美团技术团队

百度APP-Android H5首屏优化实践

总结

以上是小编为你收集整理的Android WebView开发(三):WebView性能优化全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

原文地址:https://zhongyao.blog.csdn.net

今天关于Android:如何在 webview 内容中制作双倍宽度和双倍高度的文本的介绍到此结束,谢谢您的阅读,有关Android WebView 系列文章 1 - 关于 WebView 基本使用介绍、android webview 设置字体大小后 webview高度不会缩小、Android WebView从WebViewClient到Activity通信、Android WebView开发(三):WebView性能优化等更多相关知识的信息可以在本站进行查询。

本文标签: