【问题标题】:Inflating WebView is slow since Lollipop自 Lollipop 以来,膨胀 WebView 很慢
【发布时间】:2017-10-25 08:58:09
【问题描述】:

其实我很惊讶我在 Stackoverflow 中没有发现类似的问题,但我真的想不通。

首先请注意,这与在 WebView 内浏览网页的性能无关。它只是膨胀甚至是空的 WebView,而不加载任何 URL。

为了消除所有其他因素,我创建了一个全新的项目,其中包含重现问题所必需的内容。

在这个几乎是空的项目中,我的布局只包含一个 WebView:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.testing.WebViewOnlyActivity">

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

我有一个MainActivity,它只包含一个Button,它以WebViewOnlyActivity开头:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, WebViewOnlyActivity.class);
                startActivity(intent);
            }
        });
    }
}

够简单吧?

现在,当我构建项目时,单击按钮,WebViewOnlyActivity 需要超过 1 秒才能弹出。但是,如果我按下返回按钮,然后再次按下按钮,WebViewOnlyActivity 会立即出现。 显然 Android 缓存了一些 WebView

这是我的测试设备:
1. Android 7.1.1:慢
2. Android 7.0.0:慢
3. Android 5.0.2 慢
4. Android 4.4.1 快

所以在我看来,这只是在 Lollipop 之后才发生的。

但是,这种 1.x 秒的延迟对我来说仍然是不可接受的。有谁知道如何解决它? (嗯,我认为这很难,因为我没有对这个 WebView 做任何事情......也许我应该使用一些 3rd 方 WebView?)

附:我还使用 traceview 来查看 7.1.1 设备和 4.4.1 设备之间的区别。很明显WebView'sinit()方法占用了很多时间。

7.1.1: 更深一层:

4.4.1: 更深一层:

大不同!


虽然确实是空的,但是应Axel的要求,我也会贴出WebViewOnlyActivity的代码:

public class WebViewOnlyActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view_only);

    }
}

【问题讨论】:

  • Android 4.4 开始使用 Chromium 作为渲染引擎 developer.android.com/guide/webapps/migrating.html 然后,Android 7.0 默认切换到多进程 WebView developer.android.com/about/versions/nougat/… 所以,我无法解释为什么你会看到从 4.4 到 5.0 的变化。话虽这么说,在您的屏幕截图中,我看到 200 毫秒......到达 1 秒的 800 多毫秒在哪里?
  • 如果布局中没有 webview,延迟会消失吗?
  • @AxelD。是的。它会立即出现。
  • @XavierRubioJansana 实际上,即使我杀死应用程序并重新启动,webview 也比重新启动要快一点。我认为这是因为 Android 在内存中缓存了一些 WebView 所需的资源,杀死应用程序不会删除这些缓存。比如我在app A中打开了一个WebView,在app B中打开WebView也会加快。但是我觉得上面显示的显着差异足以说明问题,所以我没有提
  • 我不知道如何解决它,它看起来像一个操作系统问题,但我可以建议两种可能的解决方法。首先,您可以在适当的时候(例如,在onStart 之后)通过代码在之前的Activity 中创建一个隐藏的WebView,然后将其销毁。这将“启动”操作系统缓存。另一种选择是将WebView 替换为ViewStub,以便在onStart 之后延迟加载WebView。用户会很快看到Activity,然后会加载WebView

标签: java android performance webview


【解决方案1】:

编辑 2017-12-21

我什至创建了一个库来轻松解决这个问题。
你可以下载它here.
觉得有用的话给个star吧:P


感谢@XavierRubioJansana 的提示,我尝试ViewStub 来延缓通货膨胀。

但是,即使我将通货膨胀延迟到onResume(),它仍然会减慢活动的创建速度。

但是如果我使用HandlerpostDelay 的通货膨胀,活动会立即创建!

    Handler webViewInflateHandler = new Handler();
    webViewInflateHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (!webViewInflated) {
                webView = (WebView) webViewStub.inflate();
                webViewInflated = true;
            }
        }
    }, 50);

然后,您需要延迟WebView 的各种设置和加载,直到它膨胀。我会建议在这里使用 RxJava 来观察BehaviorSubject&lt;Boolean&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多