java.lang.InstantiationException:不能实例化类...没有空的构造 [英] java.lang.InstantiationException: can't instantiate class ... no empty constructor

查看:3549
本文介绍了java.lang.InstantiationException:不能实例化类...没有空的构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像我这样类似的问题找到的主题,但不能找到我要找到目前为止答案。
我的应用程序由一个 FragmentActivity 它承载一个 ViewPagerAdapter 在每个标签片段(FragmentPagerAdapter儿童)。
我ViewPagerAdapter在父活动的OnCreateView功能实例

  _adapter =新ViewPagerAdapter(getApplicationContext()
                         ,getSupportFragmentManager()
                         ,numOfTabs
                         , 状态);

该ViewPagerAdapter实现了最低要求的方法的getItem getCount将 getItemPosition

我的的getItem 初始化为每个位置不同的片段:

  @覆盖
公共片段的getItem(INT位置)
{
    片f =新的片断();
    Log.d(Adbox的String.format(内部ViewPagerAdapter.getItem(%S),位置));    开关(位置)
    {
        情况下0:
            Log.d(Adbox,所有的报价==);
            F = FragmentAllOffers.newInstance(_context);
            f.setRetainInstance(真);
            打破;
        情况1:
            Log.d(Adbox,附近的优惠==);
            F = FragmentNearbyOffers.newInstance(_context);
            //f.setRetainInstance(true);
            打破;
        案例2:
            Log.d(Adbox,我的优惠券==);
            F = FragmentCoupons.newInstance(_context);
            f.setRetainInstance(真);
            打破;
        案例3:
            Log.d(Adbox,账户==);
            F = FragmentAccount.newInstance(_context);
            f.setRetainInstance(真);
            //f=LayoutLocal.newInstance(_context);
            打破;
        情况4:
            Log.d(Adbox,preferences ==);
            F =片段preferences.newInstance(_context);
            f.setRetainInstance(真);
            打破;
        默认:
            打破;
    }
    返回F;
}

要调用 setRetainInstance(真)我在努力解决,我面对,但也毫无帮助。这个问题加入

最后,每个片的上面实现与作为参数的应用程序上下文公共静态的newInstance()函数。例如,FragmentNearbyOffers包含以下内容:

 公共静态的newInstance android.support.v4.app.Fragment(上下文CTX)
{
    FragmentNearbyOffers F =新FragmentNearbyOffers();
    CTX =背景;
    //集束BDL =新包();
    返回F;
}

一个更重要的信息是父活动被声明为singleInstance,我想保持这种类似这样的一些原因。

一切工作正常,但在某些时候,当活动是在后台一段时间,我尝试要么通过任务管理器或通过点击应用程序图标我得到的异常,返回到它

  android.support.v4.app.Fragment $ InstantiationException:无法实例片段com.advisor.FragmentNearbyOffers $ 1:确保类名称存在,是公开的,有一个空的构造是公共

类名肯定存在,这是公众,没有一个构造函数,就像拥有一个空..
我甚至明确添加一个空的构造但这并没有帮助,虽然我验证它被称为

从我从这里各个岗位理解的是,恢复的Andr​​oid应用程序时,是指在没有链接到原来的活动片段的FragmentPagerAdapter新实例放置..我核实这也是因为调用从内getActivity时片段我收到空..
但我不明白为什么我收到此异常,因为有一个空的构造...
我甚至不知道在哪里可以解决这个问题,因为执行进入活动的onCreate,然后立即进入片段的空构造函数,然后我得到的异常..片段的任何其他方法,即onAttach,等的onCreate在all..So不叫,好像它的构造片段时,实际上崩溃..

我附上整个堆栈跟踪我的情况下,想起来它可以帮助:

 了java.lang.RuntimeException:无法启动活动ComponentInfo {com.advisor / com.advisor.AdBoxWidgetConfigurationFragment}:android.support.v4.app.Fragment $ InstantiationException:无法实例片段com.advisor.FragmentNearbyOffers $ 1:确保类名称存在,是公开的,有一个空的构造是公开的
    在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
    在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
    在android.app.ActivityThread.access $ 700(ActivityThread.java:140)
    在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1237)
    在android.os.Handler.dispatchMessage(Handler.java:99)
    在android.os.Looper.loop(Looper.java:137)
    在android.app.ActivityThread.main(ActivityThread.java:4921)
    在java.lang.reflect.Method.invokeNative(本机方法)
    在java.lang.reflect.Method.invoke(Method.java:511)
    在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1027)
    在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
    在dalvik.system.NativeStart.main(本机方法)
    android.support.v4.app.Fragment $ InstantiationException:引起无法实例片段com.advisor.FragmentNearbyOffers $ 1:确保类名称存在,是公开的,有一个空的构造是公开的
    在android.support.v4.app.Fragment.instantiate(Fragment.java:399)
    在android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
    在android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1760)
    在android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:200)
    在com.advisor.AdBoxWidgetConfigurationFragment.onCreate(AdBoxWidgetConfigurationFragment.java:60)
    在android.app.Activity.performCreate(Activity.java:5206)
    在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
    在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
    ... 11更多
 java.lang.InstantiationException:引起不能实例类com.advisor.FragmentNearbyOffers $ 1;没有空的构造
    在java.lang.Class.newInstanceImpl(本机方法)
    在java.lang.Class.newInstance(Class.java:1319)
    在android.support.v4.app.Fragment.instantiate(Fragment.java:388)


解决方案

注意 $ 1 在错误的结束。这是一个匿名类的引用,未命名的片段 FragmentNearbyOffers


  

无法实例片段com.advisor.FragmentNearbyOffers $ 1


由于片段需要一个默认的构造函数,匿名类不能提供的,片段必须始终是一个名为类。该 Java语言规范,部分15.9.5.1 规定:


  

这是匿名类不能有一个显式声明的构造函数。


本节还说明了构造函数自动生成的,根据该匿名类被声明的上下文。所有这些构造都有参数,因此它们具有比默认的构造函数不同的签名。的综合作用是匿名类不能有默认的构造函数的签名匹配的构造函数。

您可以声明片段类在它自己的文件或声明为一个 Static Nested Class和

 公共静态类NestedFragment扩展BaseFragment {...

这两种这些方法应该工作得很好。

I have found topics with similar questions like mine but cant find the answer I am looking for so far. my application consists of a FragmentActivity which hosts a ViewPagerAdapter (child of FragmentPagerAdapter) with a fragment in each tab. My ViewPagerAdapter is instantiated in the OnCreateView function of the parent activity

_adapter = new ViewPagerAdapter(getApplicationContext()
                         , getSupportFragmentManager()
                         , numOfTabs
                         , status);

The ViewPagerAdapter implements the minimum required methods getItem, getCount and getItemPosition

My getItem initializes a different Fragment for each position:

    @Override
public Fragment getItem(int position) 
{
    Fragment f = new Fragment();
    Log.d("Adbox",String.format("Inside ViewPagerAdapter.getItem(%s)",position));

    switch(position)
    {
        case 0:
            Log.d("Adbox","All offers  ==");
            f=FragmentAllOffers.newInstance(_context);
            f.setRetainInstance(true);
            break;
        case 1:
            Log.d("Adbox","Nearby offers  ==");
            f=FragmentNearbyOffers.newInstance(_context);
            //f.setRetainInstance(true);
            break;
        case 2:
            Log.d("Adbox","My coupons  ==");
            f=FragmentCoupons.newInstance(_context);
            f.setRetainInstance(true);
            break;
        case 3:
            Log.d("Adbox","Account  ==");
            f=FragmentAccount.newInstance(_context);
            f.setRetainInstance(true);
            //f=LayoutLocal.newInstance(_context);  
            break;
        case 4:
            Log.d("Adbox","Preferences  ==");
            f=FragmentPreferences.newInstance(_context);
            f.setRetainInstance(true);
            break;
        default:
            break;
    }
    return f;
}

The call to setRetainInstance(true) was added in my effort to resolve the problem I am facing but hasn't helped either.

Finally each of the Fragments above implement a public static newInstance() function with the application context as argument. For example the FragmentNearbyOffers contains the following:

    public static android.support.v4.app.Fragment newInstance(Context ctx)
{
    FragmentNearbyOffers f = new FragmentNearbyOffers();
    ctx = context;
    //Bundle bdl = new Bundle();
    return f;
}

One more important information is that the parent activity is declared as singleInstance and I would like to keep this like this for some reasons.

Everything works fine but at some point when the activity is in the background for some time and I try to return to it either via the TaskManager or by clicking on the application icon I get the exception

android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: make sure class name exists, is public, and has an empty constructor that is public

The class name definitely exists, it's public and doesn't have a constructor which is like having an empty one.. I even added an empty constructor explicitly but this didn't help either, although I verified it is called.

From what I understood from various posts here is that Android when resuming the application, is placing in the FragmentPagerAdapter new instances of the fragments that are not linked to the original activity.. I verified this also because when calling the getActivity from inside the fragment I receive null.. But I don't understand why I am getting this Exception since there is an empty constructor... I don't even know where to fix this, since the execution enters the onCreate of the activity, then immediately goes into the empty constructors of the fragments and then I get the exception.. Any other methods of the fragments i.e. onAttach, onCreate etc are not called at all..So it seems like it's actually crashing when constructing the fragments..

I am attaching the whole stacktrace I am getting just in case it helps:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.advisor/com.advisor.AdBoxWidgetConfigurationFragment}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: make sure class name exists, is public, and has an empty constructor that is public
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
    at android.app.ActivityThread.access$700(ActivityThread.java:140)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4921)
    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:1027)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: 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.advisor.AdBoxWidgetConfigurationFragment.onCreate(AdBoxWidgetConfigurationFragment.java:60)
    at android.app.Activity.performCreate(Activity.java:5206)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
    ... 11 more
 Caused by: java.lang.InstantiationException: can't instantiate class com.advisor.FragmentNearbyOffers$1; no empty constructor
    at java.lang.Class.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1319)
    at android.support.v4.app.Fragment.instantiate(Fragment.java:388)

解决方案

Notice the $1 at the end of the error. This is a reference to an anonymous class, not the fragment named FragmentNearbyOffers:

Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1

Since fragments require a default constructor, and anonymous classes can never provide one, fragments must always be a named class. The Java Language Specification, section 15.9.5.1 states:

An anonymous class cannot have an explicitly declared constructor.

This section also explains that constructors are generated automatically, according to the context in which the anonymous class is declared. All of these constructors have parameters, thus they have a different signature than the default constructor. The combined effect is that anonymous classes can never have a constructor that matches the default constructor's signature.

You can either declare the fragment class in it's own file or declare it as a static nested class:

  public static class NestedFragment extends BaseFragment { ...

Both of those methods should work just fine.

这篇关于java.lang.InstantiationException:不能实例化类...没有空的构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆