2016-07-22 102 views
4

我有以下代码:的WebView膨胀太慢

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; 
} 

案例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:启动
11:50:36.410 onCreateView :停止
执行时间:40ms

然后我添加的WebView,不碰任何其他代码

案例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:启动
11:51:16.985 onCreateView :停止
执行时间:340ms

正如你所见,巨大的差异,我看到我的界面在第二种情况下滞后。
1)这是一个预期的行为?
2)如果是这样,我怎么能摆脱我的UI中的滞后?
预先感谢
编辑:
完整的日志第二种情况:

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 
+0

它似乎正在加载网页 –

+0

尝试加载www.google.com在您的webview并验证加载的时间。如果加载速度更快,那么另一个URL可能很慢 – Stallion

+0

@JoeRichard请参阅日志,它看起来像在做某种浏览器初始化,但我没有更改代码,也没有在任何地方调用WebView.loadUrl() –

回答

1

不要使用XML(设计)创建它在后台线程务实创建并加载页面时,再加入它到一个布局。

这里是很好Example在相对布局中以编程方式创建它。

更新:

当我们在添加任何布局控件,直到我们在Java代码中使用,我们没有做任何事情它dosent手段。

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

当你在当时通货膨胀上面写的代码在你的XML布局,当你setContentView()WebView将其给定的属性执行。

的WebView是一流的,将执行它的构造与给定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(); 
    } 

所有上面的代码仍然只在你的XML布局添加的WebView执行。

这就是为什么它的需要时间。

希望你能理解并在WebView类中添加断点并检查你的理解。

+0

thnks为链接,我会稍后研究它。但问题仍然存在,为什么布局变化会导致某种沉重的浏览器初始化工作? –

+0

是的,事实证明这是一个'WebView'消耗宝贵的时间。现在我使用懒惰实例化,所以用户认为它是一个网页需要它的时间来加载:-) –