android.view.InflateException:二进制XML文件:错误膨胀类片段

hqt*_*hqt 143 android

我有一个非常令人沮丧的错误,我无法解释.我创建了一个Android应用程序,用于Android AppCompat使其与旧版本兼容.这是我的主要活动布局文件:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         If you're not building against API 17 or higher, use
         android:layout_gravity="left" instead. -->

    <!-- The drawer is given a fixed width in dp and extends the full height of
         the container. -->
    <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.fragment.NavigationDrawerFragment" />

</android.support.v4.widget.DrawerLayout>
Run Code Online (Sandbox Code Playgroud)

这是我活动的主要代码:

public class MainActivity extends ActionBarActivity {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
   }
}
Run Code Online (Sandbox Code Playgroud)

这里的主要问题是:上面的代码几乎可以在几乎所有设备上运行(受激设备或某些真实设备).但是当我在三星S3上运行时.它注意到这个错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{view.MainActivity}: android.view.InflateException: Binary XML file line #25: Error inflating class fragment
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2081)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2106)
            at android.app.ActivityThread.access$700(ActivityThread.java:134)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1217)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4856)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.view.InflateException: Binary XML file line #25: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
            at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:316)
            at android.app.Activity.setContentView(Activity.java:1901)
            at android.support.v7.app.ActionBarActivity.superSetContentView(ActionBarActivity.java:208)
            at android.support.v7.app.ActionBarActivityDelegateICS.setContentView(ActionBarActivityDelegateICS.java:111)
            at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:76)
Run Code Online (Sandbox Code Playgroud)

请告诉我如何修复错误,谢谢:)

hqt*_*hqt 121

经过长时间的调试,我已经解决了这个问题.(虽然我还是无法解释原因).我将财产android:name改为class.(虽然在Android Document上,他们说这些属性是相同的,但它有效!)

所以,它应该改变:

 android:name="com.fragment.NavigationDrawerFragment"
Run Code Online (Sandbox Code Playgroud)

class = "com.fragment.NavigationDrawerFragment"
Run Code Online (Sandbox Code Playgroud)

所以,新的布局应该是:

<!-- As the main content view, the view below consumes the entire
     space available using match_parent in both dimensions. -->
<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- android:layout_gravity="start" tells DrawerLayout to treat
     this as a sliding drawer on the left side for left-to-right
     languages and on the right side for right-to-left languages.
     If you're not building against API 17 or higher, use
     android:layout_gravity="left" instead. -->

<!-- The drawer is given a fixed width in dp and extends the full height of
     the container. -->
<fragment android:id="@+id/navigation_drawer"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    class = "com.fragment.NavigationDrawerFragment" />
Run Code Online (Sandbox Code Playgroud)

希望这有帮助:)

  • @DownVoter:这个错误很混乱.幸运的是,我找到了解决问题的方法.如果我的帖子无法解决您的错误,我真的很抱歉,因为我也无法解释原因.但我认为它不应该得到投票.:) (7认同)
  • 对我不起作用.我很累.dev的2h并且找不到它为什么不起作用(二进制xml文件行... errror膨胀类片段).任何的想法 ? (5认同)
  • 在尝试遵循官方Android教程时遇到了这个问题.你的修复(将`android:id`改为`class`)对我有用.我也得到了一个Lint警告,将'Fragment`改为`fragment`,我做了. (4认同)
  • 我想知道您是否可靠地*没有*从`name`更改为`class`,我有一些用户报告了这个崩溃,但我自己无法重现它! (2认同)

ReZ*_*eZa 30

我无法使用提供的答案解决我的问题.最后我改变了这个:

<fragment
android:id="@+id/fragment_food_image_gallery"
android:name="ir.smartrestaurant.ui.fragment.ImageGalleryFragment"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout="@layout/fragment_image_gallery"
tools:layout="@layout/fragment_image_gallery" />
Run Code Online (Sandbox Code Playgroud)

对此:

<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="200dp" />
Run Code Online (Sandbox Code Playgroud)

,

private void showGallery() {
    ImageGalleryFragment fragment = new ImageGalleryFragment()
    getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .commit();
    }
Run Code Online (Sandbox Code Playgroud)

它的工作原理.
如果您在片段内使用它,请使用getChildFragmentManager而不是getSupportFragmentManager.


Lar*_*rsH 21

TL/DR:在创建从更高级别布局XML引用的片段期间发生异常.此异常导致较高级别的布局通胀失败,但未报告初始异常 ; 只有较高级别的通胀故障才会出现在堆栈跟踪中.要找到根本原因,您必须捕获并记录初始异常.


错误的最初原因可能是各种各样的事情,这就是为什么这里有很多不同的答案,解决了每个人的问题.一些人认为,它曾与做id,classname属性.对于其他人来说,这是由于权限问题或构建设置.对我来说,那些没有解决问题; 相反,有一个可绘制的资源只存在于drawable-ldrtl-xhdpi,而不是在适用的地方drawable.

但这些只是细节.大图片的问题是,logcat中显示的错误消息并未描述启动它的异常.当更高级别的布局XML引用片段时,将onCreateView()调用片段.当片段中发生异常时onCreateView()(例如,在对片段的布局XML进行膨胀时),会导致更高级别布局XML的膨胀失败.这种更高级别的通胀故障是在错误日志中报告为异常的.但最初的例外情况似乎没有足够好地报道.

鉴于这种情况,问题是如何在错误日志中没有显示初始异常时公开它.

解决方案非常简单:在片段的内容周围放置try/ catchonCreateView(),并在catch子句中记录异常:

public View onCreateView(LayoutInflater inflater, ViewGroup contnr, Bundle savedInstSt) {
    try {
        mContentView = inflater.inflate(R.layout.device_detail_frag, null);
        // ... rest of body of onCreateView() ...
    } catch (Exception e) {
        Log.e(TAG, "onCreateView", e);
        throw e;
    }
}
Run Code Online (Sandbox Code Playgroud)

它可能不是很明显片段类的onCreateView()这样做是为了,在这种情况下,这样做是为了那在这导致问题的布局中使用的每个片段类.例如,在OP的情况下,发生异常的应用程序代码是

at android.app.Activity.setContentView(Activity.java:1901)
Run Code Online (Sandbox Code Playgroud)

是的

   setContentView(R.layout.activity_main);
Run Code Online (Sandbox Code Playgroud)

因此,您需要捕获onCreateView()布局中引用的任何片段中的异常activity_main.

在我的情况下,根本原因异常结果是

Caused by: android.content.res.Resources$NotFoundException: Resource
   "com.example.myapp:drawable/details_view" (7f02006f)  is not a
   Drawable (color or path): TypedValue{t=0x1/d=0x7f02006f a=-1
   r=0x7f02006f}
Run Code Online (Sandbox Code Playgroud)

在我将其捕获onCreateView()并明确记录之前,此异常未显示在错误日志中.一旦记录,问题很容易诊断和修复(由于某种原因details_view.xml仅存在于ldrtl-xhdpi文件夹下).关键是捕获作为问题根源的异常并暴露它.

在你所有片段的onCreateView()方法中做这个样板并没有什么坏处.如果那里存在未捕获的异常,则无论如何都会使活动崩溃.唯一的区别是,如果你捕获并记录异常onCreateView(),你就不会知道它为什么会发生.

PS我刚刚意识到这个答案与@ DaveHubbard有关,但是使用不同的方法来查找根本原因(日志与调试器).

  • 您可能节省了我几个小时的调试时间。荣誉! (2认同)

Coo*_*Coo 15

我有同样的问题,问题,尝试了这个线程中的所有答案无济于事.我的解决方案是,我没有在Activity XML中添加ID.我认为这不重要,但确实如此.

所以在Activity XML中我有:

<fragment
    android:name="com.covle.hellocarson.SomeFragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)

但应该有:

<fragment
    android:id="@+id/some_fragment"
    android:name="com.covle.hellocarson.SomeFragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)

如果有人愿意评论为什么会这样,我会全神贯注,对其他人,我希望这会有所帮助.


Abu*_*mon 12

It might not be needed for you anymore, but if further readers find it helpful. I have exact same android.view.InflateException:...Error inflating class fragment. I had all right libraries included. Solved by adding one more user permission in the AndroidManifest.xml file i.e. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Btw I was running Android Studio 0.8.9 on Ubuntu 12.04.


Yuc*_*ong 12

我有同样的问题因为我没有实现监听器.请参阅以下代码/*Add This!*/.

public class SomeActivity extends AppCompatActivity
        implements BlankFragment.OnFragmentInteractionListener /*Add this!*/ 
{
    @Override                                                  /*Add This!*/
    public void onFragmentInteraction(Uri uri){                /*Add This!*/
    }                                                          /*Add This!*/
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,我的片段类如下:

public class SomeFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    public interface OnFragmentInteractionListener {
        public void onFragmentInteraction(Uri uri);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

当在onCreate函数中存在异常时,我也会在另一种情况下注意到同样的错误消息Fragment.我有以下内容:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    int ID = getArguments().getInt("val");

    return rootView;
} 
Run Code Online (Sandbox Code Playgroud)

因为我重用了这个片段,所以我总忘了设置参数.然后结果getArguments()null.显然,我null在这里得到一个指针异常.我建议你也要关注这样的错误.


Wan*_*ang 8

你的NavigationDrawerFragment是否扩展了android.support.v4.app.Fragment?换句话说,你导入正确的包吗?

import android.support.v4.app.Fragment;
Run Code Online (Sandbox Code Playgroud)


Fr4*_*4nz 6

我也有这个问题.我解决了它在替代进口MainActivityNavigationDrawerFragment

import android.app.Activity;
import android.app.ActionBar;
Run Code Online (Sandbox Code Playgroud)

import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
Run Code Online (Sandbox Code Playgroud)

我更新MainActivity为扩展ActionBarActivity而不是活动

public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks
Run Code Online (Sandbox Code Playgroud)

ActionBar actionBar = getSupportActionBar();用来获取ActionBar

我更新了以下功能 NavigationDrawerFragment

private ActionBar getActionBar()
{
    return ((ActionBarActivity)getActivity()).getSupportActionBar();
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ard 6

我断断续续地遇到过类似的问题。无论实际原因如何,错误消息通常只提供很少的详细信息。但我找到了一种获取更多有用信息的方法。事实证明,内部 android 类“LayoutInflater.java”(在 android.view 包中)有一个“inflate”方法,该方法会重新引发异常,但不会获取详细信息,因此您会丢失有关原因的信息。

我使用了 AndroidStudio,并在 LayoutInflator 第 539 行(在我正在使用的版本中)设置了一个断点,这是“inflate”方法中通用异常的 catch 块的第一行:

        } catch (Exception e) {
            InflateException ex = new InflateException(
                    parser.getPositionDescription()
                            + ": " + e.getMessage());
            ex.initCause(e);
            throw ex;
Run Code Online (Sandbox Code Playgroud)

如果您在调试器中查看“e”,您将看到“原因”字段。它对于提示您实际发生的情况非常有帮助。例如,我就是这样发现所包含的片段的父级必须有一个 id,即使代码中没有使用。或者 TextView 的尺寸有问题。


Ali*_*lli 6

我遇到了这个问题,并通过使用以下代码解决了它。我正在通过使用子碎片管理器开始碎片交易。

布局:

                  <fragment
                    class="com.google.android.youtube.player.YouTubePlayerSupportFragment"
                    android:id="@+id/youtube_fragment"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)

这就是我开始分段交易的方式:

   youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_fragment);
Run Code Online (Sandbox Code Playgroud)

以下代码说明了如何删除使用childfragmentmanger添加的片段。

@Override
    public void onDestroyView() {
        super.onDestroyView();

        youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_fragment);

        if (youTubePlayerFragment != null)
        {
            getChildFragmentManager().beginTransaction().remove(youTubePlayerFragment).commitAllowingStateLoss();
        }

        youTubePlayer = null;
    }
Run Code Online (Sandbox Code Playgroud)