android.support.v4.app.Fragment.setUserVisibleHint应用程序恢复的空指针

前端之家收集整理的这篇文章主要介绍了android.support.v4.app.Fragment.setUserVisibleHint应用程序恢复的空指针前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在片段代码中的应用程序简历上遇到崩溃.我从来没有看到这个崩溃,但是我已经通过TestFlight从用户那里收到了崩溃报告.
我想有一些我错过的东西,因为代码在大多数机器上运行正常.任何帮助将不胜感激.

这是调用堆栈.

  1. java.lang.NullPointerException
  2. android.support.v4.app.Fragment.setUserVisibleHint in Fragment.java on Line 819
  3. android.support.v4.app.FragmentPagerAdapter.setPrimaryItem in FragmentPagerAdapter.java on Line 130
  4. android.support.v4.view.ViewPager.populate in ViewPager.java on Line 1066
  5. android.support.v4.view.ViewPager.populate in ViewPager.java on Line 914
  6. android.support.v4.view.ViewPager.onMeasure in ViewPager.java on Line 1436
  7. android.view.View.measure in View.java on Line 15323
  8. android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
  9. android.widget.LinearLayout.measureChildBeforeLayout in LinearLayout.java on Line 1421
  10. android.widget.LinearLayout.measureVertical in LinearLayout.java on Line 698
  11. android.widget.LinearLayout.onMeasure in LinearLayout.java on Line 579
  12. android.view.View.measure in View.java on Line 15323
  13. android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
  14. android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
  15. android.view.View.measure in View.java on Line 15323
  16. android.support.v4.widget.DrawerLayout.onMeasure in DrawerLayout.java on Line 639
  17. android.view.View.measure in View.java on Line 15323
  18. android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
  19. android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
  20. android.view.View.measure in View.java on Line 15323
  21. android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
  22. android.widget.LinearLayout.measureChildBeforeLayout in LinearLayout.java on Line 1421
  23. android.widget.LinearLayout.measureVertical in LinearLayout.java on Line 698
  24. android.widget.LinearLayout.onMeasure in LinearLayout.java on Line 579
  25. android.view.View.measure in View.java on Line 15323
  26. android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
  27. android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
  28. com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure in PhoneWindow.java on Line 2155
  29. android.view.View.measure in View.java on Line 15323
  30. android.view.ViewRootImpl.performMeasure in ViewRootImpl.java on Line 1854
  31. android.view.ViewRootImpl.measureHierarchy in ViewRootImpl.java on Line 1102
  32. android.view.ViewRootImpl.performTraversals in ViewRootImpl.java on Line 1275
  33. android.view.ViewRootImpl.doTraversal in ViewRootImpl.java on Line 1000
  34. android.view.ViewRootImpl$TraversalRunnable.run in ViewRootImpl.java on Line 4218
  35. android.view.Choreographer$CallbackRecord.run in Choreographer.java on Line 725
  36. android.view.Choreographer.doCallbacks in Choreographer.java on Line 555
  37. android.view.Choreographer.doFrame in Choreographer.java on Line 525
  38. android.view.Choreographer$FrameDisplayEventReceiver.run in Choreographer.java on Line 711
  39. android.os.Handler.handleCallback in Handler.java on Line 615
  40. android.os.Handler.dispatchMessage in Handler.java on Line 92
  41. android.os.Looper.loop in Looper.java on Line 137
  42. android.app.ActivityThread.main in ActivityThread.java on Line 4744
  43. java.lang.reflect.Method.invokeNative(Native Method)
  44. java.lang.reflect.Method.invoke in Method.java on Line 511
  45. com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run in ZygoteInit.java on Line 786
  46. com.android.internal.os.ZygoteInit.main in ZygoteInit.java on Line 553
  47. dalvik.system.NativeStart.main(Native Method)

首先,我在活动的OnResume函数中设置视图寻呼机.

  1. private void initialiseViewPager()
  2. {
  3. mLoginFragment = new WeakReference<LoginFragment>(new LoginFragment());
  4. Bundle loginBundle = new Bundle();
  5. loginBundle.putInt("SpinnerIndex",HDMSLiveSession.getInstance().getSpinnerPosition());
  6. loginBundle.putString("UserName",HDMSLiveSession.getInstance().getUsername());
  7. loginBundle.putString("Password",HDMSLiveSession.getInstance().getPassword());
  8. loginBundle.putInt("Mode",HDMSLiveSession.getInstance().getConnectionMode().ordinal());
  9. loginBundle.putBoolean("LoggedIn",HDMSLiveSession.getInstance().isLoggedIn());
  10. loginBundle.putBoolean("Connected",HDMSLiveSession.getInstance().isConnected());
  11. loginBundle.putString("LoginResult",HDMSLiveSession.getInstance().getLoginResult());
  12. loginBundle.putString("System",HDMSLiveSession.getInstance().getSystem());
  13. loginBundle.putInt("code",HDMSLiveSession.getInstance().getAccessCode());
  14. loginBundle.putLong("bytesSent",mCurrentSB);
  15. loginBundle.putLong("bytesReceived",mCurrentRB);
  16. loginBundle.putLong("nbytesSent",mNCurrentSB);
  17. loginBundle.putLong("nbytesReceived",mNCurrentRB);
  18. loginBundle.putInt("appid",mApp.getApplicationInfo().uid);
  19. loginBundle.putString(mWebSocketAddressPreference,mConnect.getWebSocketURL());
  20. loginBundle.putString(mAPIAddressPreference,mLogin.getLiveServerURL());
  21. loginBundle.putBoolean(mAutoLoginPreference,mAutoLoginEnabled);
  22. loginBundle.putBoolean(mAutoConnectPreference,mLogin.isAutoConnectEnabled());
  23. loginBundle.putInt(mAutoReconnectTimePreference,mConnect.getAutoReconnectTime());
  24. loginBundle.putInt(mMaxAutoReconnectionAttemptsPreference,mConnect.getMaxAutoReconnectionAttempts());
  25. loginBundle.putInt(mPingResponseTimePreference,mConnect.getPingResponseTime());
  26. loginBundle.putInt(mAutoPingTimePreference,mConnect.getAutoPingTime());
  27. loginBundle.putInt(mCurrentPingPreference,mConnect.getCurrentPing());
  28. loginBundle.putInt(mAutoReconnectAttemptsPreference,mConnect.getAutoReconnectAttempts());
  29. loginBundle.putInt(mAutoReconnectTotalAttemptsPreference,mConnect.getAutoReconnectTotalAttempts());
  30. loginBundle.putBoolean(mPlayListMessagePreference,messageSubscriptionContains(mPlayListMessage));
  31. loginBundle.putBoolean(mAutoPageSwapPreference,mAutoPageSwap);
  32. loginBundle.putBoolean(mWifiCheckedPreference,mWifiChecked);
  33. loginBundle.putBoolean(mAutoWebCheckedPreference,mConnect.isAutoWebChecked());
  34. loginBundle.putBoolean(mGatewayCheckedPreference,mGatewayChecked);
  35. loginBundle.putBoolean(mDHS1CheckedPreference,mDNS1Checked);
  36. loginBundle.putBoolean(mHDMSLiveCheckedPreference,mHDMSLiveChecked);
  37. loginBundle.putBoolean(mGoogleCheckedPreference,mGoogleChecked);
  38. loginBundle.putBoolean(mHDMSCheckedPreference,mHDMSChecked);
  39. loginBundle.putBoolean(mParrotCheckedPreference,mParrotChecked);
  40. loginBundle.putBoolean(mLocalIPCheckedPreference,mLocalIPChecked);
  41. loginBundle.putString(mLocalIPPreference,mLocalIP);
  42. loginBundle.putInt(mMaxImagesFromWebPreference,mMaxImagesFromWeb);
  43. loginBundle.putInt(mMaxPingAttemptsPreference,mConnect.getMaxPingAttempts());
  44. loginBundle.putInt(mFailedPingsPreference,mConnect.getFailedPings());
  45. loginBundle.putBoolean("AutoLogin",mLogin.isAutoLogin());
  46. loginBundle.putBoolean("wasLoggedIn",HDMSLiveSession.getInstance().wasLoggedIn());
  47. mLoginFragment.get().setArguments(loginBundle);
  48.  
  49. mBAUFragment = new WeakReference<BAUFragment>(new BAUFragment());
  50. Bundle bauBundle = new Bundle();
  51. bauBundle.putBoolean("jump",mJumpToCurrent);
  52. bauBundle.putInt("place",mBAUPosition);
  53. bauBundle.putBoolean(mBAUExpandedPreference,mBAUExpanded);
  54. mBAUFragment.get().setArguments(bauBundle);
  55. mPlayerFragment = new WeakReference<PlayerFragment>(new PlayerFragment());
  56.  
  57. mListFragment = new WeakReference<ListFragment>(new ListFragment());
  58. Bundle listBundle = new Bundle();
  59. listBundle.putInt(mListModePreference,mListMode);
  60. mListFragment.get().setArguments(listBundle);
  61.  
  62. mSearchFragment = new WeakReference<SearchFragment>(new SearchFragment());
  63. Bundle searchBundle = new Bundle();
  64. searchBundle.putInt(mSearchModePreference,mSearchMode);
  65. searchBundle.putString("searchQueryA",mSearchTextA);
  66. searchBundle.putString("searchQueryS",mSearchTextS);
  67. searchBundle.putString("titleLast",mTitleLast);
  68. searchBundle.putString("artistLast",mArtistLast);
  69. searchBundle.putString("listLast",mListLast);
  70. searchBundle.putString("yearLast",mYearLast);
  71. searchBundle.putString("genreLast",mGenreLast);
  72. mSearchFragment.get().setArguments(searchBundle);
  73.  
  74. mVideoFragment = new WeakReference<VideoFragment>(new VideoFragment());
  75. Bundle videoBundle = new Bundle();
  76. videoBundle.putInt(mVideoOutputPreference,mVideoOutput);
  77. mVideoFragment.get().setArguments(videoBundle);
  78.  
  79. List<Fragment> fragments = new Vector<Fragment>();
  80. fragments.add(mVideoFragment.get());
  81. fragments.add(mPlayerFragment.get());
  82. fragments.add(mBAUFragment.get());
  83. fragments.add(mListFragment.get());
  84. fragments.add(mSearchFragment.get());
  85. fragments.add(mLoginFragment.get());
  86. mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),fragments);
  87.  
  88. mViewPager = (ViewPager)findViewById(R.id.contentViewPager);
  89. mViewPager.setAdapter(mPagerAdapter);
  90. mViewPager.setOnPageChangeListener(this);
  91. mViewPager.setVisibility(View.VISIBLE);
  92.  
  93. ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
  94. if (am.getMemoryClass() >= 32)
  95. mViewPager.setOffscreenPageLimit(Fragments.Max.ordinal());
  96.  
  97. mLastFragment = -1;
  98. UpdateDisplay();
  99. }

除非是具有小内存堆的设备,否则所有碎片都将被保留.目前有6个片段,崩溃发生时只有4个内存.所以我知道碎片的数量不是问题.我确实尝试将视图寻呼机设置设置为默认值,唯一的区别是速度,因为应用程序需要在用户刷新时加载碎片.当应用程序暂停时,所有碎片都将被销毁.

  1. @Override
  2. protected void onSaveInstanceState(Bundle outState)
  3. {
  4. FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  5. if (mLoginFragment.get() != null)
  6. ft.remove(mLoginFragment.get());
  7. if (mPlayerFragment.get() != null)
  8. ft.remove(mPlayerFragment.get());
  9. if (mBAUFragment.get() != null)
  10. ft.remove(mBAUFragment.get());
  11. if (mListFragment.get() != null)
  12. ft.remove(mListFragment.get());
  13. if (mSearchFragment.get() != null)
  14. ft.remove(mSearchFragment.get());
  15. if (mVideoFragment.get() != null)
  16. ft.remove(mVideoFragment.get());
  17. ft.commit();
  18.  
  19. mLoginFragment = new WeakReference<LoginFragment>(null);
  20. mPlayerFragment = new WeakReference<PlayerFragment>(null);
  21. mBAUFragment = new WeakReference<BAUFragment>(null);
  22. mListFragment = new WeakReference<ListFragment>(null);
  23. mSearchFragment = new WeakReference<SearchFragment>(null);
  24. mVideoFragment = new WeakReference<VideoFragment>(null);
  25. mPagerAdapter = null;
  26. mViewPager = null;
  27.  
  28. mFragmentsLoaded = 0;
  29. mLastFragment = -1;
  30. }

这是我的观点寻呼机代码.

  1. package com.hdms.manager.Fragments;
  2.  
  3. /**
  4. * Created by bradj on 8/10/13.
  5. *
  6. */
  7. import android.support.v4.app.Fragment;
  8. import android.support.v4.app.FragmentManager;
  9. import android.support.v4.app.FragmentPagerAdapter;
  10. import android.support.v4.app.FragmentTransaction;
  11. import android.view.View;
  12.  
  13. import java.util.List;
  14.  
  15. public class ViewPagerAdapter extends FragmentPagerAdapter
  16. {
  17. private final List<Fragment> mFragments;
  18. FragmentManager mFragmentManager;
  19.  
  20. public ViewPagerAdapter(FragmentManager aFragmentManager,List<Fragment> aFragments)
  21. {
  22. super(aFragmentManager);
  23.  
  24. mFragmentManager = aFragmentManager;
  25. mFragments = aFragments;
  26. }
  27.  
  28. @Override
  29. public Fragment getItem(int aPosition)
  30. {
  31. return mFragments.get(aPosition);
  32. }
  33.  
  34. @Override
  35. public long getItemId(int aPosition)
  36. {
  37. return aPosition;
  38. }
  39.  
  40. @Override
  41. public void destroyItem(android.view.ViewGroup aContainer,int aPosition,java.lang.Object aObject)
  42. {
  43. if (aPosition <= getCount() && aObject != null)
  44. {
  45. FragmentTransaction trans = mFragmentManager.beginTransaction();
  46. trans.remove((Fragment) aObject);
  47. trans.commit();
  48. }
  49. }
  50.  
  51. @Override
  52. public int getCount()
  53. {
  54. return mFragments.size();
  55. }
  56. }

解决方法

最后!我现在能够可靠地重新创建这个错误

要重新创建错误,关闭活动/应用程序,并快速重新打开页面与片段.您可能需要尝试几次,因为在我的测试中,我不得不在30秒内重新打开应用程序.不同速度设备的时间可能会更慢或更快.

问题是我只显式创建了Fragment(使用new)一次,并保留了对该实例的引用,以便我可以重用它.对此问题的一个简单的解决方案是始终返回Fragment的Fragment的新实例FragmentPagerAdapter.getItem(…),如下所示.

  1. public class ViewPagerAdapter extends FragmentPagerAdapter {
  2. ...
  3.  
  4. @Override
  5. public Fragment getItem(int position) {
  6. switch (position) {
  7. case 0: return mMyFragment; // Error. Has the edge-case crash.
  8. case 1: return new MyFragment(); // Works.
  9. default: return new MyDefaultFragment();
  10. }
  11. }
  12. }

对于OP的具体情况,使用列表< Fragment>持有引用可能与上述相同的问题案例.

ps – 根问题可能与Fragment生命周期有关,并尝试在销毁它时再次使用它.

pps – 另一种重新创建错误方法是在足够的选项卡之间快速切换,以使Fragment想要被破坏,从缓存中释放一些内存,然后快速返回.默认情况下,FragmentPagerAdapter仅将一个片段缓存到“左”和“右”.因此,根据您的缓存限制,您必须至少有三个选项卡以这种方式重新创建错误.

ppps – 此解决方案修复了用于android.app.Fragment.setUserVisibleHint(Fragment.java:997)的NullPointerException,并且也适用于android.support.v4.app.Fragment.setUserVisibleHint.

猜你在找的Android相关文章