类片段膨胀错误

187

我遇到了错误。

Unable to start activity ComponentInfo{de.androidbuch.activiti/de.androidbuch.activiti.task.Activity}: android.view.InflateException: Binary XML file line #11: Error inflating class fragment

在我通过纵向和横向模式切换时,我正在使用片段。我的XML如下:

当我通过纵向和横向模式切换时,我正在使用片段。我的XML是:

 <LinearLayout android:id="@+id/mainLayout"
               android:orientation="horizontal"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content" >

    <ListView android:id="@+id/android:list"
              android:layout_height="wrap_content"
              android:layout_width="fill_parent"/> 

    <fragment android:id="@+id/fragmentDetails"
              android:layout_height="fill_parent"
              android:layout_width="fill_parent"
              class="de.androidbuch.activiti.task.TaskDetailsFragment"/> 
</LinearLayout>

如果我通过横向和纵向模式进行切换,一切正常。但是当我单击我的片段(我可以看到我的片段),然后切换到另一种模式时,我会遇到错误。有什么想法可以解决这个问题吗?在这里找到了一些答案,但没有一个能帮助我解决...

06-21 14:55:05.600: ERROR/AndroidRuntime(7636): FATAL EXCEPTION: main
06-21 14:55:05.600: ERROR/AndroidRuntime(7636): java.lang.RuntimeException: Unable to start activity         
ComponentInfo{de.androidbuch.activiti/de.androidbuch.activiti.task.Activity}:   android.view.InflateException: Binary XML file line #11: Error inflating class fragment
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1736)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1752)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3097)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.access$1600(ActivityThread.java:123)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:997)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.os.Looper.loop(Looper.java:126)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.main(ActivityThread.java:3998)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at java.lang.reflect.Method.invokeNative(Native Method)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at java.lang.reflect.Method.invoke(Method.java:491)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at dalvik.system.NativeStart.main(Native Method)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636): Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:727)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:227)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.Activity.setContentView(Activity.java:1771)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at de.androidbuch.activiti.task.TaskActivity.onCreate(TaskActivity.java:83)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1700)
06-21 14:55:05.600: ERROR/AndroidRuntime(7636):     ... 12 more

你在layout和layout-land文件夹中保持了单独的布局文件吗? - Nathan Fig
你能提供完整的错误日志,包括“无法启动活动”后面的行吗? - Dave
@Nathan Fig:是的,我有...但是出现了错误... - tsync
对于Android初学者而言,需要注意的是:在XML中,<YourSpecialView 而不是 <com.blah.blah.YourSpecialView 可能会导致这个问题 - 有时候问题就是这么简单。 - Fattie
使用FrameLayout代替Fragment。 - Kundan
显示剩余6条评论
46个回答

133

正如 hdemirchian 所说,一定要使用:

As hdemirchian said, make sure to use:

import android.support.v4.app.Fragment;

还要确保使用片段的活动扩展了FragmentActivity而不是常规的Activity

import android.support.v4.app.FragmentActivity;

获取FragmentActivity类。


15
这个帖子得到了很多点赞,但对我而言,在恢复应用程序时它会崩溃,我已经使用了v4 Fragment和v4 FrsgmentActivity - 更准确地说是AppCompatActivity。 - joseph
4
这不是解决方案。import android.support.v4.app.Fragment; 并没有改变任何事情。实际上它是一个未被使用和不必要的导入。 - f470071
8
谢谢,需要说明一下的是AppCompatActivity是FragmentActivity的子类。 - abedfar
但我正在使用Dagger Fragment,而Dagger Fragment始终扩展Fragment而不是Fragment Activity。 - Ankita Singh

108

如果您在onActivityCreated()被调用之前就在片段内操作getActivity(),则可能会出现异常android.view.InflateException: Binary XML file line: #... Error inflating class fragment。在这种情况下,您将收到一个错误的活动引用,不能依赖它。

例如,下面的模式是错误的:

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

    Button button = getActivity().findViewById(R.id...);
    button.setOnClickListener(...); - another problem: button is null

    return view;
}

正确的模式 #1

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

    Button button = view.findViewById(R.id...);
    button.setOnClickListener(...);

    return view;
}

正确的模式 #2

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Button button = getActivity().findViewById(R.id...);
    button.setOnClickListener(...);
}

@MaximKorobov你可以在onActivityCreated()或任何后续的生命周期方法中调用getActivity(),但在onDestroyView()之前。 - Grigori A.
我很想了解更多关于这个问题,我的程序偶尔会崩溃,我认为这可能是问题所在。虽然大部分时间代码都能正常运行,所以很难确定。 - Daniel Wilson
模式2也许对我有用。祈求好运。谢谢。 - joseph
就是这样了!谢谢! - Tino
这真的非常有帮助!! - Abhi
显示剩余2条评论

55

确保你的Activity继承自FragmentActivity


2
注意:FragmentActivity是Support Library提供的一种特殊活动,用于处理系统版本低于API级别11的片段。如果您支持的最低系统版本是API级别11或更高,则可以使用常规Activity。 - Munib
1
@RobinF,AppCompatActivity继承自FragmentActivity。 - Nicola Gallazzi
这对我起作用了。 - Ismail Osunlana

46

我也遇到了同样的错误。我整天都在苦苦寻找解决方法,尝试了大约25种解决方案,但都没有奏效,直到凌晨2点我才发现我在应用清单XML中漏掉了这一行:

<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />

那行代码位于 <application> 标签内。我真的希望这对某人有所帮助。祝好。


4
我的英雄。像你这样的人让世界变得如此美好! - capdragon
10
请解释一下正在发生的事情。这条线有什么好处? - Mansour Fahad
3
谢谢,救了我的一天。在安卓上使用Google地图的每个样本都有所不同,我想知道是否有一个标准。 - user2812866

22

我曾遇到同样的问题。对于我来说,解决方案是在FragmentActivity中按正确顺序调用super.onCreate和setContentView方法。

以下顺序可以正常工作:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.fc_activity_list_profiles);

1
在JAVA方法中,super必须始终在方法的开头被调用。 - Stéphane Bruckert
11
@StéphaneBruckert 并不总是要先调用 super.method(),这取决于父类方法的具体实现。在 FragmentActivity 中,它执行了一些必要的初始化工作以使 setContentView 正常工作。然而,在另一个方法中(比如 onKeyUp),您可能想有条件地对操作进行一些处理,但最后还是需要回退到 super.onKeyUp,这种情况下,您很可能会希望在函数的最后调用 super.onKeyUp - CoatedMoose
值得注意的是,在任何子类构造函数中,super()(超类的构造函数)都必须是第一个被调用的函数,但并不一定强制要求调用它(这完全取决于被扩展的类)。 - CoatedMoose

19

XML中不能嵌套片段

通过我艰难的学习得知,如果在从FragmentManager动态加载的片段中嵌套基于XML布局的<fragment>标签,则会开始出现奇怪的错误,尝试填充片段XML。

事实证明,这是不被支持的 - 如果您纯粹使用FragmentManager方法执行此操作,则可以正常工作。

我遇到了这个问题,因为我试图在XML中加载一个片段,该片段位于<DrawerLayout>内,并且当我弹出返回栈时,这会导致onCreateView()方法崩溃。


这还没有支持吗?截止到appcompat-v7:23.3.0 - Thanassis
是的,我正在将片段嵌套在XML中。我会研究一下。 - KDeogharkar
但是对于这个问题存在解决方案/黑科技:https://dev59.com/Qeo6XIcBkEYKwwoYOR0q#14695397 - Morten Holmgaard
2
请参考本节末尾的注释以确认:https://developer.android.com/about/versions/android-4.2.html#NestedFragments - Philippe
不确定为什么解决方案如此简单。对我来说,只需将“<fragment>”替换为“<frameLayout>”即可解决问题。我还在摸索中。- https://dev59.com/2HfZa4cB1Zd3GeqPTJLJ#19167009 - yoad w

16

我曾经遇到和你一样的问题。 上面的所有提示都没有对我有所帮助。 后来,我发现我只需要修复从以下位置引入的内容:

import android.app.Fragment;
至:
import android.support.v4.app.Fragment;

谢谢,这个解决方案对我也起作用了。我为此问题苦恼了两天。最终你的解决方案对我有用了。感谢hdemirchian.. - Lakshmanan
你太棒了!我的问题正好相反——Fragment向导默认导入android.support.v4.app.Fragment,而我的主活动扩展了android.app.Activity。 - Industrial Control Freak

12

你尝试过这个吗:

 <fragment
            android:name="de.androidbuch.activiti.task.TaskDetailsFragment"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

1
你向我们展示了1个XML文件,但你应该有2个,一个在/layout/目录下,另一个在layout-land/目录下。 - Blundell

12

确保在片段的onCreateView方法中没有引发任何异常。如果在该方法中引发了任何异常,logcat将不会显示异常的详细信息,而总是显示以下消息:

Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.fragment" 
on path: DexPathList[[zip file "/data/app/com.package/base.apk"],
nativeLibraryDirectories=[/data/app/com.package/lib/arm64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

只是补充一下雷所说的,将try catch放在oncreateview内部的代码周围,并找出实际的根本原因。谢谢雷! - Swaroop

6
如果你的TaskDetailsFragment继承自android.app.Fragment,请在onCreateView()中进行更改。
返回你想要在Fragment中显示的视图,或者使用LayoutInflater将你的布局转换为视图并返回它。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View mainview = inflater.inflate(R.layout.main, null);
    return mainview;
}

希望这个能够运作。 :)

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