安卓webview加载数据速度非常缓慢

40

你好,我正在开发一个应用,在其中使用了Android WebView。每当我启动WebView活动时,都会从test.txt文件中以字符串HTML格式加载数据。 test.txt文件包含将近2.5 MB的数据,加载完test.txt文件后,如果滑动屏幕到末尾以读取所有数据并按返回键,则随后启动Webview活动需要更长时间来呈现数据。在第一次启动Webview时需要最少的时间。在启动此活动期间,我没有遇到任何错误/异常/崩溃。

我正在使用Android API 18及以上版本

注意:我已经对这个问题进行了大量的研究。我尝试了Android WebView slowAndroid WebView performance中的解决方案,但都没有用。

我不能使用android:hardwareAccelerated="true"<--因为它有很多副作用(虽然我仍然使用了它,但在这个问题上没有发现任何变化)。

我不能使用webview.getSettings().setRenderPriority(RenderPriority.HIGH);

setRenderPriority() --> 这个方法在API级别18中已被弃用。不建议调整线程优先级,这在将来的版本中将不受支持。

我的DataLoader.java类

public class DataLoader extends Activity {

    private WebView webView = null;
    // Progress Dialog
    private ProgressDialog progressDialog;

    String dataContent = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.web_view);
        webView = (WebView)findViewById(R.id.text);

        // Loading webview in Background Thread
        new LoadWebView().execute();
    }

    class LoadWebView extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(DataLoader.this);
            progressDialog.setTitle("Loading...");
            progressDialog.setMessage("Please wait.");
            progressDialog.setCancelable(false);
            progressDialog.setIndeterminate(true);
            progressDialog.show();
        }

        protected String doInBackground(String... args) {
            // AssetFileReader read the txt file and return data in the form of string
            dataContent = AssetFileReader.read(getApplicationContext(), "test.txt");

            return null;
        }

        protected void onPostExecute(String str) {
            // dismiss the dialog
            progressDialog.dismiss();

            if (dataContent != null) {
                // updating UI from Background Thread
                runOnUiThread(new Runnable() {
                    public void run() {

                        WebSettings s = webView.getSettings();
                        s.setUseWideViewPort(true);
                        s.setSupportZoom(true);
                        s.setBuiltInZoomControls(true);
                        s.setDisplayZoomControls(false);
                        s.setJavaScriptEnabled(true);
                        webView.loadData(dataContent, "text/html", "utf-8");
                    }
                });
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        webView.clearCache(true);
        webView.clearHistory();
    }
}

我的web_view.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/text">
    </WebView>

</LinearLayout>

如果您对此问题有任何解决方法,请告诉我。


仅仅启用setJavaScriptEnabled会导致速度变慢。目前我还没有找到原因。 - Muhammed Yalçın Kuru
3个回答

72

我认为以下方式最有效:

if (Build.VERSION.SDK_INT >= 19) {
    webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}       
else {
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

安卓19采用了Chromium引擎作为WebView。我猜这样可以更好地使用硬件加速。

更多信息请参阅Android 4.4 KitKat,浏览器和Chrome WebView

硬件加速也能起到作用。您可以在应用程序中的不同级别使用它。

应用程序级别

<application android:hardwareAccelerated="true" ...>

活动水平

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

窗位

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

查看级别

myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);

但是正如你在问题中已经提到的,你可以详细说明一下这种方法的副作用吗?


4
请发布副作用!启用硬件加速以更快地加载 WebView,我认为这并不是必要的。 - Jorgesys
@King of Masses 请在视图层将LAYER_TYPE_SOFTWARE更改为LAYER_TYPE_HARDWARE。 - M.ArslanKhan
1
@Jorgesys,请详细说明一下副作用,如果您知道的话? - MDT

9
我已经尝试下面的代码,它对我来说运行速度更快。
// For API level below 18 (This method was deprecated in API level 18)
webview.getSettings().setRenderPriority(RenderPriority.HIGH); 

webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
if (Build.VERSION.SDK_INT >= 19) {
    webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}       
else {
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

10
setRenderPriority()方法现已过时。 - Mohanakrrishna

1
如果有人仍在苦苦挣扎地尝试让WebViews渲染更快,可以尝试使用Crosswalk的XWalkView。它在我们的应用程序中产生了巨大的影响。

3
它已经不再受支持。 (https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview) - MDT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接