6

में कोई भी फ़ंक्शन शामिल नहीं है मेरे पास एक ऐप है जो आईसीएस में एक्शन बार पर टैब का उपयोग करता है, जहां प्रत्येक टैब में इसके अंदर एक टुकड़ा होता है। कुछ परिस्थितियों में, जब मैंने एक्शन बार पर विकल्प मेनू पर एक बटन दबाया है, तो डिवाइस को घुमाएं, मुझे एक NullPointerException मिलता है। मैं इसे चरणों के एक ही सेट के साथ विश्वसनीय रूप से पुन: उत्पन्न कर सकता हूं, लेकिन कुछ मामले हैं (जैसे कि मैं एक्शन बार पर किसी भी बटन को धक्का नहीं देता) अपवाद उत्पन्न नहीं करता है। अपवाद मेरे कोड में किसी भी पंक्ति का संदर्भ नहीं प्रतीत होता है, और एक अभिविन्यास परिवर्तन के बाद गतिविधि के मनोरंजन के दौरान होता है।प्रेषण के दौरान रोटेशन पर NullPointerExceptionCreateOptionsMenu, स्टैक ट्रेस में मेरे ऐप

यहाँ अपवाद है:

09-18 20:56:22.357: E/AndroidRuntime(689): FATAL EXCEPTION: main 
09-18 20:56:22.357: E/AndroidRuntime(689): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.andavapps.flightbot/com.andavapps.flightbot.FlightBotActivity}: java.lang.NullPointerException 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3351) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.access$700(ActivityThread.java:123) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.os.Handler.dispatchMessage(Handler.java:99) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.os.Looper.loop(Looper.java:137) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.main(ActivityThread.java:4424) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at java.lang.reflect.Method.invoke(Method.java:511) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at dalvik.system.NativeStart.main(Native Method) 
09-18 20:56:22.357: E/AndroidRuntime(689): Caused by: java.lang.NullPointerException 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:1831) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.Activity.onCreatePanelMenu(Activity.java:2445) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:388) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:739) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.policy.impl.PhoneWindow.restorePanelState(PhoneWindow.java:1664) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1619) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.Activity.onRestoreInstanceState(Activity.java:906) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.Activity.performRestoreInstanceState(Activity.java:878) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1100) 
09-18 20:56:22.357: E/AndroidRuntime(689):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934) 
09-18 20:56:22.357: E/AndroidRuntime(689):  ... 12 more 

और यहाँ मेरी गतिविधि कोड है

public class MyActivity extends Activity { 

    private class MyTabListener<C extends MyFragment> implements ActionBar.TabListener { 

     private Activity activity; 
     private MyFragment fragmentMain; 
     private MyFragment fragmentSide; 
     private Class<C> cls; 

     public MyTabListener(Activity a, Class<C> c) { 
      activity = a; 
      cls = c; 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      if (sidebar) { 
       if (fragmentSide == null) { 
        fragmentSide = (MyFragment) Fragment.instantiate(activity, cls.getName()); 
        ft.add(c.SIDE_FRAME, fragmentSide, fragmentSide.getViewTag()); 
       } else 
        ft.attach(fragmentSide); 
      } else { 
       if (fragmentMain == null) { 
        fragmentMain = (MyFragment) Fragment.instantiate(activity, cls.getName()); 
        ft.add(c.MAIN_FRAME, fragmentMain, fragmentMain.getViewTag()); 
       } else 
        ft.attach(fragmentMain); 
      } 
      selected = tabs.indexOf(tab); 
      mainUp = false; 
      if (setUpComplete) 
       invalidateOptionsMenu(); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      if (fragmentSide != null && !fragmentSide.isDetached()) 
       ft.detach(fragmentSide); 
      if (fragmentMain != null && !fragmentMain.isDetached()) 
       ft.detach(fragmentMain); 
     } 

    } 

    private class MyMainTabListener<C extends MyFragment> implements ActionBar.TabListener { 

     private Activity activity; 
     private MyFragment fragmentMain; 
     private Class<C> cls; 

     public MyMainTabListener(Activity a, Class<C> c) { 
      activity = a; 
      cls = c; 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      if (fragmentMain == null) { 
       fragmentMain = (MyFragment) Fragment.instantiate(activity, cls.getName()); 
       ft.add(c.MAIN_FRAME, fragmentMain, fragmentMain.getViewTag()); 
      } else if (fragmentMain.isDetached()) 
       ft.attach(fragmentMain); 
      mainUp = !sidebar; 
      if (setUpComplete) 
       invalidateOptionsMenu(); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      if (!sidebar && fragmentMain != null && !fragmentMain.isDetached()) 
       ft.detach(fragmentMain); 
      else if (sidebar && (fragmentMain == null || fragmentMain.isDetached())) { 
       if (fragmentMain == null) { 
        fragmentMain = (MyFragment) Fragment.instantiate(activity, cls.getName()); 
        ft.add(c.MAIN_FRAME, fragmentMain, fragmentMain.getViewTag()); 
       } else if (fragmentMain.isDetached()) 
        ft.attach(fragmentMain); 
      } 
     } 

    } 

    private static final class c { 
     //A bunch of constants are defined here 
    } 

    private ArrayList<ActionBar.Tab> tabs = new ArrayList<ActionBar.Tab>(); 

    private int side; 
    private int orient; 
    private int selected; 
    private boolean sidebar; 
    private boolean mainUp; 
    private boolean lock; 
    private boolean setUpComplete = false; 

    @Override 
    public void onCreate(Bundle inState) { 
     super.onCreate(inState); 
     setContentView(R.layout.main_rel); 

     orient = detectOrientation(); 

     if (inState != null) { 
      selected = inState.getInt("selected", 1); 
      side = inState.getInt("side", c.LEFT_SIDE); 
      sidebar = inState.getBoolean("visible", true); 
      mainUp = inState.getBoolean("mainup", !sidebar); 
      lock = inState.getBoolean("lock", false); 
     } else { 
      selected = 1; 
      side = c.LEFT_SIDE; 
      sidebar = true; 
      mainUp = false; 
      lock = false; 
     } 

     ActionBar ab = getActionBar(); 
     ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     tabs.add(ab.newTab().setText(MainFragment.getTabText()).setTabListener(new MyMainTabListener<MainFragment>(this, MainFragment.class))); 
     tabs.add(ab.newTab().setText(OtherFragment.getTabText()).setTabListener(new MyTabListener<OtherFragment>(this, OtherFragment.class))); 
     tabs.add(ab.newTab().setText(AnotherFragment.getTabText()).setTabListener(new MyTabListener<AnotherFragment>(this, AnotherFragment.class))); 
     tabs.add(ab.newTab().setText(YetAnotherFragment.getTabText()).setTabListener(new MyTabListener<YetAnotherFragment>(this, YetAnotherFragment.class))); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 

     if (!setUpComplete) 
      setUp(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if (!setUpComplete) 
      setUp(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     setUpComplete = false; 
     getActionBar().removeAllTabs(); 

     super.onSaveInstanceState(outState); 
     outState.putInt("selected", selected); 
     outState.putInt("side", side); 
     outState.putBoolean("visible", sidebar); 
     outState.putBoolean("mainup", mainUp); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     menu.findItem(R.id.menu_showhide).setTitle(c.MENU_SHOW_TEXT[(sidebar ? 1 : 0)]).setIcon(c.MENU_SHOW_DRAW[(sidebar ? 1 : 0)][side][orient][(mainUp ? 0 : 1)]); 
     menu.findItem(R.id.menu_swapside).setTitle(c.MENU_SIDE_TEXT[side][orient]).setIcon(c.MENU_SIDE_DRAW[side][orient]); 
     menu.findItem(R.id.menu_lock).setTitle(c.MENU_LOCK_TEXT[(lock ? 1 : 0)]).setIcon(c.MENU_LOCK_DRAW[(lock ? 0 : 1)]); 
     if (!sidebar) 
      menu.findItem(R.id.menu_swapside).setVisible(false).setEnabled(false); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.menu_swapside: 
       toggleSide(); 
       return true; 
      case R.id.menu_showhide: 
       toggleVisibility(); 
       return true; 
      case R.id.menu_lock: 
       toggleRotation(); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    private int detectOrientation() { 
      int o = getResources().getConfiguration().orientation; 
      int r = getWindowManager().getDefaultDisplay().getRotation(); 

      if (o == Configuration.ORIENTATION_LANDSCAPE && (r == Surface.ROTATION_0 || r == Surface.ROTATION_90)) 
       return c.LAND_ORIENT; 
      else if (o == Configuration.ORIENTATION_PORTRAIT && (r == Surface.ROTATION_90 || r == Surface.ROTATION_180)) 
       return c.RPORT_ORIENT; 
      else if (o == Configuration.ORIENTATION_LANDSCAPE && (r == Surface.ROTATION_180 || r == Surface.ROTATION_270)) 
       return c.RLAND_ORIENT; 
      else 
       return c.PORT_ORIENT; 
    } 

    private void toggleVisibility() { 
     sidebar = !sidebar; 
     mainUp = !sidebar; 
     invalidateOptionsMenu(); 
     setUpTabs(); 
    } 

    private void toggleSide() { 
     side = (side == c.RIGHT_SIDE ? c.LEFT_SIDE : c.RIGHT_SIDE); 
     invalidateOptionsMenu(); 
     setUpSide(); 
    } 

    private void toggleRotation() { 
     lock = !lock; 
     invalidateOptionsMenu(); 
     setUpLock(); 
    } 

    private void setUp() { 
     setUpTabs(); 
     setUpSide(); 
     setUpLock(); 
     setUpComplete = true; 
    } 

    private void setUpTabs() { 
     ActionBar ab = getActionBar(); 
     ab.removeAllTabs(); 

     ab.addTab(tabs.get(0), sidebar || mainUp); 
     if (sidebar) 
      ab.removeTab(tabs.get(0)); 
     for (int i = 1; i < tabs.size(); i ++) 
      ab.addTab(tabs.get(i), !mainUp && selected == i); 
    } 

    private void setUpSide() { 
     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); 
     params.addRule(c.SIDE_RULE[side][orient], c.SIDE_FRAME); 
     FrameLayout mf = (FrameLayout) findViewById(c.MAIN_FRAME); 
     mf.setLayoutParams(params); 

     params = new RelativeLayout.LayoutParams(c.LAYOUT_WIDTH[orient], c.LAYOUT_HEIGHT[orient]); 
     params.addRule(c.ALIGN_RULE[side][orient]); 
     FrameLayout sf = (FrameLayout) findViewById(c.SIDE_FRAME); 
     sf.setLayoutParams(params); 
    } 

    private void setUpLock() { 
     setRequestedOrientation((lock ? c.LOCK_ORIENT[orient] : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)); 
    } 

} 

मेरे ऐप और समझाने के लिए कोड के बारे में कुछ नोट्स (इसे यहाँ दिखाने का सादगी के लिए कुछ असंबंधित कोड निकाला गया) चीजें:

  • ऐप मुख्य टुकड़ा और साइडबार खंड
  • प्रदर्शित करता है
  • विकल्प मेनू में तीन बटन होते हैं: एक साइडबार को स्क्रीन के एक तरफ से दूसरी तरफ स्विच करने के लिए, एक साइडबार को छिपाने के लिए, और एक ओरिएंटेशन को लॉक करने के लिए
  • मुख्य खंड हमेशा टैब सूची में पहला होता है और हमेशा मेनफ्रैगमेंट
  • टाइप किया गया है, मैं इसे आईसीएस (एसस ट्रांस प्राइम, 4.0.4) चलाने वाले दो उपकरणों पर चला रहा हूं; एचटीसी विशद, 4.0.3) & एम्यूलेटर (आईसीएस 4.0.3 & जेबी 4.1)। यह केवल आईसीएस पर होता है।

अपवाद निम्न क्रम के साथ होता है:

  • ऐप्लिकेशन लॉन्च
  • प्रेस बटन साइडबार

को छिपाने के लिए

  • घुमाने डिवाइस कुछ और डिवाइस घूर्णन से पहले होता है, अपवाद नहीं होता है। उदाहरण के लिए यदि साइडबार अप्रयुक्त है, तो मुझे अपवाद नहीं मिलता है। यदि डिवाइस पहले घुमाया जाता है, तो अपवाद कभी नहीं होगा, इसलिए यदि साइडबार छुपा हुआ है, और डिवाइस फिर से घूमता है, तो मुझे अपवाद नहीं मिलता है। और स्टैक ट्रेस मेरे कोड में एक ही फ़ंक्शन का संदर्भ नहीं देता है, इसलिए मैं मूल कारण का पता लगाने के लिए भी प्रतीत होता हूं।

    ऐसा लगता है इस FragmentManager.java (पैकेज android.app) कि अपवाद फेंकता में समारोह है:

    1827  public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    1828   boolean show = false; 
    1829   ArrayList<Fragment> newMenus = null; 
    1830   if (mActive != null) { 
    1831    for (int i=0; i<mAdded.size(); i++) { 
    1832     Fragment f = mAdded.get(i); 
    1833     if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { 
    1834      show = true; 
    1835      f.onCreateOptionsMenu(menu, inflater); 
    1836      if (newMenus == null) { 
    1837       newMenus = new ArrayList<Fragment>(); 
    1838      } 
    1839      newMenus.add(f); 
    1840     } 
    1841    } 
    1842   } 
    1843   
    1844   if (mCreatedMenus != null) { 
    1845    for (int i=0; i<mCreatedMenus.size(); i++) { 
    1846     Fragment f = mCreatedMenus.get(i); 
    1847     if (newMenus == null || !newMenus.contains(f)) { 
    1848      f.onDestroyOptionsMenu(); 
    1849     } 
    1850    } 
    1851   } 
    1852   
    1853   mCreatedMenus = newMenus; 
    1854   
    1855   return show; 
    1856  } 
    

    mAdded पर कोई अशक्त जांच के लिए इसका इस्तेमाल करने के लिए प्रयास करने से पहले नहीं है। जेबी में एक ही कार्य (mActive != null)(mAdded != null) के साथ बदलता है। लेकिन मुझे नहीं पता कि आईसीएस के लिए मैं इससे बचने के लिए कामकाज के रूप में क्या कर सकता हूं।

    किसी के पास कोई विचार है? मैंने स्टैक ओवरव्लो को इसी तरह के मुद्दों की तलाश में खराब कर दिया है, लेकिन अब तक खाली आ गया है। धन्यवाद! अगर कुछ और है तो मुझे पोस्ट करने की ज़रूरत है, मुझे बताएं और मैं इसे जोड़ दूंगा।

  • +0

    आप लाइन नंबर अपवाद में बरकरार रख सकते हैं: मैं एप्लिकेशन संदर्भ संदर्भ जहां मैं कर सकता और बातिल के लिए टुकड़े में सभी शेष गतिविधि संदर्भ परीक्षण द्वारा करने के लिए Activity संदर्भ बदलकर एनपीई समस्याओं से बचने के। आप इसे चलाने के लिए जेलीबीन एमुलेटर का उपयोग कर रहे हैं? – nandeesh

    +0

    मैंने काफी समय बिताया है डीबगिंग, और इसे किसी स्रोत पर नहीं ढूंढ सकता, यही कारण है कि मैं स्टैक ओवरफ्लो में बदल रहा हूं। अपवाद में कोई पंक्ति संख्या नहीं है, क्योंकि वे सभी सिस्टम फ़ंक्शंस हैं। लाइन नंबर बहुत अच्छा होगा, क्योंकि तब मैं एंड्रॉइड स्रोत पर जा सकता हूं और सटीक कारण बता सकता हूं। जैसा कि है, मैं एंड्रॉइड स्रोत में उस स्टैक ट्रेस में अधिकांश फ़ंक्शंस से गुजर चुका हूं और बहुत कुछ नहीं ढूंढ सकता। मैं इसे दो अलग अलग भौतिक डिवाइसों पर चल रहा हूँ (दोनों से एक ही बात मिलता है) - 4.0.4 और एक एचटीसी विविड चल 4.0.3 – bjg222

    +0

    ठीक चल रहा है एक Asus Transformer Prime, मैं एमुलेटर पर इसे चलाने के लिए मौका मिला है एक भौतिक डिवाइस की बजाय, और स्टैक ट्रेस में मूल एंड्रॉइड फ़ंक्शंस के लिए लाइन नंबर शामिल हैं। मैंने कुछ और विवरणों के साथ प्रश्न भी अपडेट किया है। यह पता चला है कि यह जेबी में नहीं होता है, बस आईसीएस। (पहले कोशिश नहीं की है, क्योंकि मेरा ऐप 4.0 और ऊपर लक्षित है) – bjg222

    उत्तर

    3

    मेरे पास एक ऐप है जो टूलबार का उपयोग करता है (com.example.android.actionbarcompat पर आधारित कोड) जहां मैं एक ही समस्या में भाग गया।कुछ उपकरणों पर, onrereOptionsMenu() को ऑनरेट() के ठीक बाद नहीं कहा जाता है जिसका अर्थ है कि एक्शन बार प्रारंभ नहीं किया गया था, और जब मैंने आइकन बदलने की कोशिश की, तो ऐप क्रैश हो गया।

    मेरे लिए अच्छी खबर यह है कि onCreateOptionsMenu() कुछ बाद में कहा जाता हो जाता है और जब ऐसा होता है, मैं एक संदर्भ मेनू में onCreateOptionsMenu में (रखने के लिए)। मैंने एक्शन बार के साथ कुछ भी करने से पहले इस संदर्भ को देखने के लिए अपने शेष गतिविधि कोड को संशोधित किया। यह अभी भी सुपर फास्ट निष्पादित करता है, और उपयोगकर्ता अनुभव प्रभावित नहीं होता है।

    मैं तुम्हें भी ऐसा ही करने के लिए और कुछ प्रारंभ स्थगित सुझाव देते हैं।

    +0

    ठीक है, प्रारंभिक अवस्था मुझे वैसे भी आम तौर पर एक अच्छा विचार के रूप में हमला करता है। मैं निश्चित रूप से इसे आज़मा दूंगा और देख सकता हूं कि यह समस्या को हल करता है या नहीं। – bjg222

    0

    अपनी गतिविधि टैग में यह जोड़ें:

    android:configChanges="orientation" 
    

    और ओवरराइड इस विधि:

    public void onConfigurationChanged(Configuration newConfig) 
    

    आप में अधिक जानकारी प्राप्त कर सकते हैं:

    http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)

    http://developer.android.com/reference/android/R.attr.html#configChanges

    0

    मैं एक ऐप्लिकेशन है जो टैब और एनपीई रोटेशन परिवर्तन पर में Fragments था के साथ एक समान मुद्दा था। कारण यह था कि ActivityFragments में संदर्भ कभी-कभी शून्य थे।

    if(getActivity() != null) { 
        getActivity.someMethod() 
    }; 
    

     संबंधित मुद्दे

    • कोई संबंधित समस्या नहीं^_^