Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebView inflates 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 see there's huge difference and I see my interface lagging in the second case.
1) Is this an intended behaviour?
2) If so how can I get rid of lags in my UI?
Thanks in advance
Edit:
The full log of 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
like image 571
Stephan Leila Avatar asked Jul 22 '16 06:07

Stephan Leila


1 Answers

Dont Create it using XML (Design) create it pragmatically in background thread and when page loaded then add it to a layout.

here is good Example of creating it programmatically in relative layout.

Update:

When we add any widget in layout its dosent means we are not doing anything until we use 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 above code in you XML Layout at the time inflation when you setContentView() WebView will execute with its given attributes.

WebView is class it will execute its constructor with given attributes set

 /**
     * 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 above code still execute by only adding WebView in your xml layout.

Thats why its taking time.

Hope you will understand and add break points in WebView class and check for your understanding.

like image 90
Sohail Zahid Avatar answered Oct 30 '22 03:10

Sohail Zahid