2013-05-09 130 views
4

我發現了類似於我的問題的主題,但找不到我目前爲止所找到的答案。 我的應用程序由一個FragmentActivity組成,其中包含ViewPagerAdapter(FragmentPagerAdapter的子項),每個選項卡中都有一個片段。 我ViewPagerAdapter在父活動java.lang.InstantiationException:無法實例化類...沒有空的構造函數

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

的ViewPagerAdapter的OnCreateView功能實例實現了最小所需的方法getItemgetCountgetItemPosition

getItem初始化不同片段的每個位置:

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

致電setRetainInstance(true)是爲了解決我的問題而添加的面對但也沒有幫助。

最後,上面的每個片段實現了一個公共靜態newInstance()函數,其中應用程序上下文作爲參數。例如,FragmentNearbyOffers包含以下內容:

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

一個更重要的信息是父活動被聲明爲singleInstance,我想保持這種類似這樣的一些原因。

一切工作正常,但在某些時候,當活動是在後臺一段時間,我嘗試要麼通過任務管理器或通過點擊應用程序圖標我得到的異常返回到它

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 

類名肯定存在,它是公共的,並沒有一個構造函數,就像有一個空的構造函數。我甚至明確添加了一個空的構造函數,但這也沒有幫助,雖然我證實它被調用。

從我從這裏的各種帖子瞭解到的是,Android在恢復應用程序時,正在將未鏈接到原始活動的碎片的新實例放置在FragmentPagerAdapter中。我驗證了這一點,這也是因爲在調用getActivity時在我收到空片段 但我不明白爲什麼我得到這個異常,因爲有一個空的構造函數...我不知道在哪裏解決這個,因爲執行進入的onCreate活動,然後立即進入片段的空構造函數,然後我得到異常..片段的任何其他方法,即onAttach,onCreate等根本不會被調用..因此,似乎它實際上是在構造片段時崩潰。 。

我附上整個堆棧跟蹤我得到以防萬一它有助於:

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

我想你應該發佈你的整個FragmentActivity類 – 2013-05-09 14:54:36

+0

。你有沒有嘗試重新啓動eclipse? – Blackbelt 2013-05-09 15:14:40

+0

我設法解決了這個問題..這是一個非常棘手的問題,因爲這個異常消息是誤導性的。在我的片段中,我有另一個嵌套的片段,我在運行時創建了一個內部類。 '' – giannisdoe 2013-05-11 18:18:09

回答

2

我設法解決這個問題。它是相當棘手的一個,因爲異常消息是誤導。在我的片段中,我有另一個嵌套的片段,我在運行時創建了一個內部類。

 mMapFragment = new SupportMapFragment() 
    { 
     @Override 
     public void onResume() 
     { 
      // TODO Auto-generated method stub 
      super.onResume(); 
      //initMap(); 
     } 

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

      map = mMapFragment.getMap(); 
      if (map != null) 
      { 
       // map.setMapType(GoogleMap.MAP_TYPE_NONE); 
       map.setMyLocationEnabled(true); 
       CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(lat, lng)); 
       zoom = CameraUpdateFactory.zoomTo(18); 
       map.moveCamera(center); 
       map.animateCamera(zoom); 
      } 

     } 
    }; 

由於應用程序是由Android殺害後,恢復回它的時候,機器人再現的片段,我猜它不可能重新嵌套一個因爲內部類的構造函數是不可見的。按照其他一些帖子的建議,我把課程移到了一個單獨的文件中,並且它工作正常。

+0

我在同一個文件中聲明它是一個公共靜態類,它也可以正常工作。片段實例不能是匿名類。 – 2013-05-31 20:49:59

7

注意錯誤結束時的$1。這是一個匿名類的引用,沒有命名FragmentNearbyOffers片段:

無法實例片段com.advisor.FragmentNearbyOffers $ 1

由於片段需要一個默認的構造函數和匿名類不能提供一,片段必須始終是一個命名類。該Java Language Specification, section 15.9.5.1狀態:

匿名類不能有一個明確的聲明的構造。

本節還解釋了構造函數是根據聲明匿名類的上下文自動生成的。所有這些構造函數都有參數,因此它們具有與默認構造函數不同的簽名。綜合的效果是匿名類永遠不會有一個匹配默認構造函數簽名的構造函數。

您可以聲明片段類在它自己的文件或聲明爲一個Static Nested Class和

public static class NestedFragment extends BaseFragment { ... 

兩種這些方法應該只是罰款。

相關問題