Android InstantiationException with Fragment(它是公开的)

Posted

技术标签:

【中文标题】Android InstantiationException with Fragment(它是公开的)【英文标题】:Android InstantiationException With Fragment (It Is Public) 【发布时间】:2012-12-11 10:51:09 【问题描述】:

我有一个Fragment(它不是内部类,也没有任何构造函数)

public class PreferenceListFragment extends ListFragment implements OnClickListener

我在 android 开发者控制台上收到了这个崩溃报告:

java.lang.RuntimeException: Unable to start activity 
ComponentInfocom.redacted.redacted/com.redacted.redacted.PreferenceActivity: 
android.support.v4.app.Fragment$InstantiationException: 
Unable to instantiate fragment com.redacted.redacted.PreferenceListFragment$3:
make sure class name exists, is public, and has an empty constructor that is
public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1750)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1766)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2960)
at android.app.ActivityThread.access$1600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:945)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3818)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.support.v4.app.Fragment$InstantiationException: 
Unable to instantiate fragment com.redacted.redacted.PreferenceListFragment$3: 
make sure class name exists, is public, and has an empty constructor that
is public
at android.support.v4.app.Fragment.instantiate(Fragment.java:399)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1760)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:200)
at com.redacted.redacted.PreferenceActivity.onCreate(PreferenceActivity.java:37)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1710)
... 12 more
Caused by: java.lang.InstantiationException: 
com.redacted.redacted.PreferenceListFragment$3
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1409)
at android.support.v4.app.Fragment.instantiate(Fragment.java:388)
... 18 more

我无法在我的任何测试设备上复制它。

这是发生异常的PreferenceActivity.onCreate

public class PreferenceActivity extends FragmentActivity

    PreferenceListFragment frag;

    @Override
    public void onCreate(Bundle savedInstanceState)
        super.onCreate(savedInstanceState);

        setContentView(R.layout.preference);

        frag = (PreferenceListFragment) getSupportFragmentManager().
                findFragmentById(R.id.preference_list_frag);
        frag.setState(AlarmPreferenceState.Selected);
        frag.setIsTwoPane(false);
    

    .
    .
    .

这里是R.layout.preference

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <fragment class="com.redacted.redacted.PreferenceListFragment"
          android:id="@+id/preference_list_frag"
          android:layout_
          android:layout_/>

</FrameLayout>

有人知道我为什么会得到这个异常,和/或如何重现它吗?

【问题讨论】:

我没有从这个问题中完全理解这一点:除了无参数之外,您的 PreferenceListFragment 类是否还有其他构造函数? 它没有构造函数....不久前我在Fragment 上遇到了另一个问题,SO 上的某个人说Fragment 中没有任何构造函数 PreferenceListFragment 类是其他类的内部类吗?如果是,则将其设为static,否则您将获得该异常。 @Luksprog 更新了问题以反映它不是内部类。我也无法重现这个(我从开发者控制台得到了异常) 当你说它没有构造函数时,你的意思是连一个空的都没有吗?见here。 【参考方案1】:

MUST 有一个空的公共构造函数。谁告诉你不要有片段构造函数,把你引向了错误的方向。

他们可能告诉你的是,没有接受参数的构造函数,因为在重新创建片段时系统可能不会调用这些构造函数。在这种情况下,请使用文档中的示例为您的片段提供参数。

引用自文档:

Fragment 的所有子类都必须包含一个公共的空构造函数。框架通常会在需要时重新实例化一个片段类,特别是在状态恢复期间,并且需要能够找到这个构造函数来实例化它。如果空构造函数不可用,在状态恢复过程中某些情况下会出现运行时异常。 [1],[2]

[1]:https://developer.android.com/reference/android/app/Fragment.html

[2]:https://developer.android.com/reference/android/app/Fragment.html#Fragment()

【讨论】:

我会尝试添加一个,看看是否会弹出更多错误。谢谢! 默认构造函数始终存在,除非我们将其设为私有。【参考方案2】:

检查您的保护规则

在我的情况下奇怪的是,这个错误只在发布版本中弹出,而不是在调试版本中。

问题是,我使用 FragmentContainerView 来保存 Fragment 并在 XML 本身中提到了 Fragment 类名,就像这样

<androidx.fragment.app.FragmentContainerView
                android:id="@+id/f_navigation_fragment"
                class="com.example.MyFragmentClass"
                android:layout_
                android:layout_ />

这在 Debug 版本中运行良好(没有 Proguard 混淆),但在 Release 版本中 (带有 Proguard 混淆),实际的 Fragment 类被混淆了,因此XML 无法找到它导致 OP 的错误。

请参阅this 链接以获取更多参考资料。

【讨论】:

【参考方案3】:

当我不小心尝试导航到 abstract Fragment 类时出现此错误。

【讨论】:

以上是关于Android InstantiationException with Fragment(它是公开的)的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)

【Android笔记】android Toast

图解Android - Android核心机制

Android游戏开发大全的目录