Al *_*ath 8 android illegalstateexception android-fragments
我FragmentTransaction.replace()用来交换碎片进出.该应用程序第一次启动没有问题.IllegalStateException由于savedInstanceState与提交新的片段事务之间存在冲突,因此在旋转设备时会抛出An .没有涉及AsyncTask.
一个StackOverflow问题建议将setContentView()呼叫置于其中onResumeFragments(),但这似乎没有效果.与...相同onPostResume().
另一个StackOverflow问题说要覆盖onConfigurationChanged().从某种意义上说,这是因为没有重新启动Activity,所以不会发生异常.但是,这可以防止具有不同纵向和横向布局的片段在这些布局之间切换.调用setContentView()中onConfigurationChanged()
导致类似的错误(抛出:IllegalArgumentException:二进制XML文件行#25:复制ID为0x12345678,标记为空,或父ID与另一片段)
使用fragmentTransaction.commitAllowingStateLoss()而不是.commit()原因IllegalStateException:Activity已被销毁.
我如何让它工作?
更多异常信息:
了java.lang.RuntimeException:无法启动活动ComponentInfo {MYAPP/myap.MainActivity}:
android.view.InflateException:二进制XML文件行#25:myapp.MainActivity.onResumeFragments(MainActivity.java:450)错误充气类片段
引起by:java.lang.IllegalStateException:无法在myapp.fragments.FragmentChange.onFragmentChange(FragmentChange.java:128)的> android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1533)的onSaveInstanceState之后执行此操作at myapp.MainActivity.onNavigationDrawerItemSelected(MainActivity.java:490)myapp.fragments.NavigationDrawerFragment.selectItem(NavigationDrawerFragment.java:197)at myapp.fragments.NavigationDrawerFragment.onCreate(NavigationDrawerFragment.java:78)at myapp.MainActivity.onResumeFragments( MainActivity.java:450)
旋转设备时代码中的顺序是:
MainActivity.onPause()
MainActivity.saveInstanceState()
NavigationDrawerFragment.onSaveInstanceState()
MainActivity.onStop()
MainActivity.onDestroy()
MainActivity.onCreate()
super.onCreate(savedInstanceState);
MainActivity.onResumeFragments()
setContentView()
NavigationDrawerFragment.onCreate()
MainActivity.onNavigationDrawerItemSelected()
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)
主要活动:
public class MainActivity extends AppCompatActivity implements
NavigationDrawerFragment.NavigationDrawerCallbacks {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
@Override
public void onNavigationDrawerItemSelected(int position) {
...
FragmentChangeEvent fragmentChangeEvent = new FragmentChangeEvent(null);
FragmentChange fragmentChange = FragmentChange.getInstance( getSupportFragmentManager());
fragmentChange.onFragmentChange(fragmentChangeEvent);
...
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
super.onSaveInstanceState(outState);
}
@Override
public void onResumeFragments() {
super.onResumeFragments();
// causes onNavigationDrawerItemSelected() to be called, exception thrown
setContentView(myapp.R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(myapp.R.id.navigation_drawer);
mNavigationDrawerFragment.setUp( // Set up the drawer
myapp.R.id.navigation_drawer,
(DrawerLayout) findViewById(myapp.R.id.drawer_layout));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if current fragment is "Individual" { // pseudocode
setContentView(R.layout.activity_main); // causes IllegalArgumentException
}
}
}
Run Code Online (Sandbox Code Playgroud)
NavigationDrawerFragment
public class NavigationDrawerFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
// calls MainActivity.onNavigationDrawerItemSelected()
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
}
Run Code Online (Sandbox Code Playgroud)
FragmentChange
public class FragmentChange implements FragmentChangeListener {
public static FragmentChange getInstance(FragmentManager fragmentManager) {
if (instance == null) {
instance = new FragmentChange(fragmentManager);
}
return instance;
}
// constructor
private FragmentChange(FragmentManager fragmentManager) {
mFragmentManager = fragmentManager;
}
@Override
public void onFragmentChange(FragmentChangeEvent fragmentChangeEvent) {
...
mPosition = fragmentChangeEvent.getPosition();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
Fragment fragment = EmployeesVerticalFragment.newInstance();
fragmentTransaction.replace(myapp.R.id.container, fragment);
fragmentTransaction.commit(); // IllegalState exception here
...
}
}
Run Code Online (Sandbox Code Playgroud)
FragmentManager 是一个
用于与Activity 内部的Fragment 对象交互的接口。
在我看来,将其保存在静态字段中并为新活动重用旧的 FragmentManager 是一个特别糟糕的主意。当新活动与旧活动的管理器交互时,这必然会导致活动被销毁。
在您的代码中,替换
FragmentChange.getInstance(getFragmentManager());
Run Code Online (Sandbox Code Playgroud)
经过
new FragmentChange(getFragmentManager());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1481 次 |
| 最近记录: |