我无法在应用中跟踪崩溃原因。我有一个显示ListView
的片段,我还有一个搜索字段SlidingMenu
。当我搜索时,ListView
项目将根据搜索结果重新填充。现在,当我尝试从新填充的结果中打开ListView
项时,我的应用程序崩溃了。
此处触发异常:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mContent", mContent); //Exception made here
}
这是因为支持库吗?我该如何解决这个问题?
修改
这是堆栈跟踪:
02-05 12:51:53.941: E/AndroidRuntime(11638): FATAL EXCEPTION: main
02-05 12:51:53.941: E/AndroidRuntime(11638): java.lang.IllegalStateException: Fragment MyFragment{436749b0} is not currently in the FragmentManager
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.support.v4.app.FragmentManagerImpl.putFragment(FragmentManager.java:546)
02-05 12:51:53.941: E/AndroidRuntime(11638): at com.sample.android.app.SearchListActivity.onSaveInstanceState(SearchListActivity.java:118)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.Activity.performSaveInstanceState(Activity.java:1137)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1215)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2972)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3031)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.ActivityThread.access$900(ActivityThread.java:138)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.os.Handler.dispatchMessage(Handler.java:99)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.os.Looper.loop(Looper.java:213)
02-05 12:51:53.941: E/AndroidRuntime(11638): at android.app.ActivityThread.main(ActivityThread.java:4787)
02-05 12:51:53.941: E/AndroidRuntime(11638): at java.lang.reflect.Method.invokeNative(Native Method)
02-05 12:51:53.941: E/AndroidRuntime(11638): at java.lang.reflect.Method.invoke(Method.java:511)
02-05 12:51:53.941: E/AndroidRuntime(11638): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
02-05 12:51:53.941: E/AndroidRuntime(11638): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
02-05 12:51:53.941: E/AndroidRuntime(11638): at dalvik.system.NativeStart.main(Native Method)
编辑2: 这是我的活动:
private Fragment mFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
..........
params = new Bundle();
params.putInt("id", id);
// set the Above View Fragment
if (savedInstanceState != null)
mFragment = getSupportFragmentManager().getFragment(
savedInstanceState, "mFragment");
else {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
SampleListFragment fragment = new SampleListFragment();
fragment.setArguments(params);
fragmentTransaction.add(R.id.list_fragment, fragment);
fragmentTransaction.commit();
}
if (mFragment == null) {
mFragment = new SampleListFragment();
mFragment.setArguments(params);
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.list_fragment, mFragment).commit();
// set the Behind View Fragment
Fragment searchFragment = new SampleSearchFragment();
searchFragment.setArguments(params);
getSupportFragmentManager().beginTransaction()
.replace(R.id.activity_search, searchFragment)
.commit();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mFragment",
mFragment);
}
在我的SampleListFragment
中,我有这种方法:
public static boolean isNetworkAvailable(Activity activity) {
ConnectivityManager connectivity = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return false;
} else {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
Asynctask
内部:
..........
@Override
protected void onPostExecute(String result) {
super.onPostExecute(null);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
if (isNetworkAvailable(getActivity())) { //Triggered NPE
从here开始,如何在调用之前知道getActivity()
是否已附加到父活动?
答案 0 :(得分:30)
在onSaveInstanceState
中保存片段之前,请确保检查片段是否已添加到片段管理器
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mFragment.isAdded()){
getSupportFragmentManager().putFragment(outState, "mFragment", mFragment);
}
}
答案 1 :(得分:1)
我也面临同样的问题。当我尝试将片段放在bundleState中
时@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mContent", mContent); //Exception made here
}
我检查了putFragment()
中FragmentManager
方法的实施情况。就像
@Override
public void putFragment(Bundle bundle, String key, Fragment fragment) {
if (fragment.mIndex < 0) {
throwException(new IllegalStateException("Fragment " + fragment
+ " is not currently in the FragmentManager"));
}
bundle.putInt(key, fragment.mIndex);
}
其中mIndex
是片段索引到活动片段数组。因此,如果mIndex < 0
表示片段当前不活动。因此@FelipeConde建议检查mFragment.isAdded()
可能是最佳解决方案。
答案 2 :(得分:1)
最近,我遇到了同样的问题。 就我而言,我忘了在调用活动onBackPressed()时设置mFragment。也就是说,当用户浏览A - &gt; B - &gt; C,mFragment相应地更改为A,然后是B,最后是C.但是,当按下后退时,当前片段反向更改为B,然后是A,但mFragment仍为C.因此,在onSaveInstanceState期间,活动尝试保存C它不再出现在FragmentManager中了。
重点是,您可能在不适当更改mFragment的情况下更改(添加或删除)当前[显示]片段。
答案 3 :(得分:1)
在我的情况下,我有2个片段( PopularMoviesFragment和TopRatedMoviesFragement ), PopularMoviesFragment 填充在Activity的onCreate中,另一个则单击< strong> BottomNavigationView 。
因此,当我打开应用程序并且没有单击 BottomNavigationView 时,如果我最小化(或导航到其他应用程序),则会收到此异常
java.lang.IllegalStateException:Fragment TopRatedMoviesFragement {79d8905}当前不在FragmentManager中
我在onCreate()中的代码为
if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {
fragmentManager.beginTransaction()
.replace(R.id.containerw, fragment_1, FRAGMENT_1)
.addToBackStack(null)
.commit();
}else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){
fragmentManager.beginTransaction()
.replace(R.id.container, fragment_2, FRAGMENT_2)
.addToBackStack(null)
.commit();
}
因此,我所做的只是添加了 TopRatedMoviesFragement ,然后将其替换为 PopularMoviesFragment ,如下面的代码所示。
if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {
fragmentManager.beginTransaction()
.add(R.id.container, fragment_2, FRAGMENT_2)
// Its been added to avoid Fragment is not currently in the FragmentManager
.replace(R.id.container, fragment_1, FRAGMENT_1)
.addToBackStack(null)
.commit();
}else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){
fragmentManager.beginTransaction()
.replace(R.id.container, fragment_2, FRAGMENT_2)
.addToBackStack(null)
.commit();
}
希望这也有帮助。 :)
答案 4 :(得分:0)
就我而言,片段通过FragmentPagerAdapter添加到ViewPager,以便有多个标签,每个标签1个片段。
List<Android.Support.V4.App.Fragment> lsFragments = new List<Android.Support.V4.App.Fragment>();
lsFragments.Add(m_FragmentListDocument);
lsFragments.Add(m_FragmentListNote);
lsFragments.Add(m_FragmentListRenvoi);
m_viewPager.Adapter = new TabsFragmentPagerAdapter(SupportFragmentManager, lsFragments, lsTitles);
在我的OnSaveInstanceState中,我想保存所有标签,但是1个标签正在抛出异常Java.Lang.IllegalStateException: Fragment is not currently in the FragmentManager
:
protected override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
SupportFragmentManager.PutFragment(outState, "FragmentListDocument", m_FragmentListDocument);
SupportFragmentManager.PutFragment(outState, "FragmentListNote", m_FragmentListNote);
SupportFragmentManager.PutFragment(outState, "FragmentListRenvoi", m_FragmentListRenvoi);
}
这是由于ViewPager:ViewPager加载屏幕上显示的当前片段,并且(默认情况下)加载左侧和右侧的片段。
因此,在这种情况下,我修改了ViewPager,将OffscreenPageLimit设置得足够高,以便在启动时加载所有片段。然后将片段添加到SupportFragmentManager中,并且不在OnSaveInstanceState中抛出异常。
m_viewPager.OffscreenPageLimit = 4;
希望它会有所帮助...