Java – WebView bloat too slowly

WebView bloat too slowly… here is a solution to the problem.

WebView bloat too slowly

I have the following code:

public View onCreateView(LayoutInflater _inflater, ViewGroup _group, Bundle _savedInstanceState) {
    Log.w(getClass().getName(), "start");
    View view = _inflater.inflate(R.layout.myLayout, _group, false);
    Log.w(getClass().getName(), "stop");
    return view;
}

Case 1:

//myLayout.xml
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView 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"/>
</FrameLayout>

11:50:36.370 onCreateView: start
11:50:36.410
onCreateView: stop
Execution time: 40ms

Then I add a WebView and don’t touch any other code

Case 2:

//myLayout.xml
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView 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"/>
    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

11:51:16.645 onCreateView: start
11:51:16.985
onCreateView: stop
Execution time: 340ms

As you can see, there is a huge difference between the two, and I find that my interface lags in the second case.
1) Is this intentional?
2) If so, how can I eliminate lag in the UI?
Thanks
in advance
Edit:
Full log for the second case:

11:51:16.645 onCreateView: start
11:51:16.710 I/WebViewFactory: Loading com.google.android.webview version 51.0.2704.81 (code 270408100)
11:51:16.740 W/art: Suspending all threads took: 11.333ms
11:51:16.755 I/cr_LibraryLoader: Time to load native libraries: 2 ms (timestamps 5137-5139)
11:51:16.755 I/cr_LibraryLoader: Expected native library version number "51.0.2704.81", actual native library version number "51.0.2704.81"
11:51:16.765 V/WebViewChromiumFactoryProvider: Binding Chromium to main looper Looper (main, tid 1) {1d66229a}
11:51:16.765 I/cr_LibraryLoader: Expected native library version number "51.0.2704.81", actual native library version number "51.0.2704.81"
11:51:16.765 I/chromium: [INFO:library_loader_hooks.cc(143)] Chromium logging enabled: level = 0, default verbosity = 0
11:51:16.795 I/cr_BrowserStartup: Initializing chromium process, singleProcess=true
11:51:16.805 E/ApkAssets: Error while loading asset assets/natives_blob_64.bin: java.io.FileNotFoundException: assets/natives_blob_64.bin
11:51:16.805 E/ApkAssets: Error while loading asset assets/snapshot_blob_64.bin: java.io.FileNotFoundException: assets/snapshot_blob_64.bin
11:51:16.870 W/cr_media: Requires BLUETOOTH permission
11:51:16.885 I/art: Rejecting re-init on previously-failed class java.lang.Class<com.android.webview.chromium.WebViewContentsClientAdapter$WebResourceErrorImpl>
11:51:16.885 I/art: Rejecting re-init on previously-failed class java.lang.Class<com.android.webview.chromium.WebViewContentsClientAdapter$WebResourceErrorImpl>
11:51:16.920 D/ConnectivityManager.CallbackHandler: CM callback handler got msg 524290
11:51:16.935 11557-11588/? W/FlurryAgent: Flurry session ended
11:51:16.945 I/art: Rejecting re-init on previously-failed class java.lang.Class<org.chromium.content.browser.FloatingWebActionModeCallback>
11:51:16.945 I/art: Rejecting re-init on previously-failed class java.lang.Class<org.chromium.content.browser.FloatingWebActionModeCallback>
11:51:16.970 D/cr_Ime: [InputMethodManagerWrapper.java:30] Constructor
11:51:16.980 W/cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
11:51:16.980 D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: false
11:51:16.985 onCreateView: stop

Solution

Don’t create it with XML (design) actually create it in a background thread and add it to the layout when the page loads.

Here’s nice< a href="https://stackoverflow.com/questions/11221777/webview-in-programmatically-created-relativelayout" rel="noreferrer noopener nofollow">Example Create it programmatically in a relative layout.

Update:

When we add any widget to the layout, its dosent means that we won’t do anything until we use it in our java code.

   <WebView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/webView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

When you write the above code in an XML layout, the setContentView() WebView will execute using its given properties.

A WebView is a class that executes its constructor using the given set of properties

 /**
     * Constructs a new WebView with a Context object.
     *
     * @param context a Context object used to access application assets
     */
    public WebView(Context context) {
        this(context, null);
    }

/**
     * Constructs a new WebView with layout parameters.
     *
     * @param context a Context object used to access application assets
     * @param attrs an AttributeSet passed to our parent
     */
    public WebView(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.webViewStyle);
    }

/**
     * Constructs a new WebView with layout parameters and a default style.
     *
     * @param context a Context object used to access application assets
     * @param attrs an AttributeSet passed to our parent
     * @param defStyleAttr an attribute in the current theme that contains a
     *        reference to a style resource that supplies default values for
     *        the view. Can be 0 to not look for defaults.
     */
    public WebView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

/**
     * Constructs a new WebView with layout parameters and a default style.
     *
     * @param context a Context object used to access application assets
     * @param attrs an AttributeSet passed to our parent
     * @param defStyleAttr an attribute in the current theme that contains a
     *        reference to a style resource that supplies default values for
     *        the view. Can be 0 to not look for defaults.
     * @param defStyleRes a resource identifier of a style resource that
     *        supplies default values for the view, used only if
     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
     *        to not look for defaults.
     */
    public WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        this(context, attrs, defStyleAttr, defStyleRes, null, false);
    }

/**
     * Constructs a new WebView with layout parameters and a default style.
     *
     * @param context a Context object used to access application assets
     * @param attrs an AttributeSet passed to our parent
     * @param defStyleAttr an attribute in the current theme that contains a
     *        reference to a style resource that supplies default values for
     *        the view. Can be 0 to not look for defaults.
     * @param privateBrowsing whether this WebView will be initialized in
     *                        private mode
     *
     * @deprecated Private browsing is no longer supported directly via
     * WebView and will be removed in a future release. Prefer using
     * {@link WebSettings}, {@link WebViewDatabase}, {@link CookieManager}
     * and {@link WebStorage} for fine-grained control of privacy data.
     */
    @Deprecated
    public WebView(Context context, AttributeSet attrs, int defStyleAttr,
            boolean privateBrowsing) {
        this(context, attrs, defStyleAttr, 0, null, privateBrowsing);
    }

/**
     * Constructs a new WebView with layout parameters, a default style and a set
     * of custom Javscript interfaces to be added to this WebView at initialization
     * time. This guarantees that these interfaces will be available when the JS
     * context is initialized.
     *
     * @param context a Context object used to access application assets
     * @param attrs an AttributeSet passed to our parent
     * @param defStyleAttr an attribute in the current theme that contains a
     *        reference to a style resource that supplies default values for
     *        the view. Can be 0 to not look for defaults.
     * @param javaScriptInterfaces a Map of interface names, as keys, and
     *                             object implementing those interfaces, as
     *                             values
     * @param privateBrowsing whether this WebView will be initialized in
     *                        private mode
     * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to
     *       be added synchronously, before a subsequent loadUrl call takes effect.
     */
    protected WebView(Context context, AttributeSet attrs, int defStyleAttr,
            Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
        this(context, attrs, defStyleAttr, 0, javaScriptInterfaces, privateBrowsing);
    }

/**
     * @hide
     */
    @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
    protected WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
            Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
        super(context, attrs, defStyleAttr, defStyleRes);
        if (context == null) {
            throw new IllegalArgumentException("Invalid context argument");
        }
        sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
                Build.VERSION_CODES. JELLY_BEAN_MR2;
        checkThread();

ensureProviderCreated();
        mProvider.init(javaScriptInterfaces, privateBrowsing);
         Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
        CookieSyncManager.setGetInstanceIsAllowed();
    }

All of the above code is still executed by simply adding a WebView to your XML layout.

That’s why it takes time.

Hope you understand and add a breakpoint in the WebView class and check your understanding.

Related Problems and Solutions