当用户单击关闭按钮关闭 DialogFragment 时出现 IllegalStateException
Posted
技术标签:
【中文标题】当用户单击关闭按钮关闭 DialogFragment 时出现 IllegalStateException【英文标题】:IllegalStateException when the user clicks the Close button to dismiss a DialogFragment 【发布时间】:2016-11-15 19:36:51 【问题描述】:我从我的一些用户那里得到了这个例外:
java.lang.IllegalStateException: 之后无法执行此操作 onSaveInstanceState 在 android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManagerImpl.java:1500) 在 android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManagerImpl.java:1518) 在 android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634) 在 android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613) 在 android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:201) 在 android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:167) 在 com.myapp.myapp.HelpDialog$2.onClick(HelpDialog.java:228) 在 android.view.View.performClick(View.java:5201) 在 android.view.View$PerformClick.run(View.java:21163) 在 android.os.Handler.handleCallback(Handler.java:746) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5443) 在 java.lang.reflect.Method.invoke(Method.java) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
导致此异常的调用位于 DialogFragment onCreateView() 方法中:
...
Button btn;
btn = (Button)v.findViewById( R.id.close_btn );
btn.setOnClickListener( new View.OnClickListener()
@Override
public void onClick( View view )
dismiss();
);
dismiss 导致状态丢失,因为该操作是在 onSaveInstanceState() 之后完成的。调用 onSaveInstanceState() 后,用户如何点击关闭按钮?
编辑。 DialogFragment 里面有一个viewpager。我将只发布 dialogfragment 的代码,而不是 viewpager 适配器或 fragmenttabs 的代码:
/**
*
*/
public class HelpDialog extends DialogFragment
final static String DIALOG_TAG = "help_dialog";
ViewPager mPager = null;
/**
*
*/
public HelpDialog()
CLog.i( "HelpDialog.HelpDialog()", "Constructor called" );
/**
* Create a new instance of WelcomeDialog.
*/
static HelpDialog newInstance()
HelpDialog d = new HelpDialog();
return d;
/**
*
*/
static boolean showNewInstance( FragmentActivity activity )
HelpDialog d = HelpDialog.newInstance();
if ( d != null )
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
Fragment prev = activity.getSupportFragmentManager().findFragmentByTag( HelpDialog.DIALOG_TAG );
if (prev != null)
ft.remove( prev );
// Create and show the dialog.
d.show( ft, HelpDialog.DIALOG_TAG );
return true;
return false;
@Override
public void onCreate( Bundle savedInstanceState )
super.onCreate(savedInstanceState);
CLog.i("HelpDialog.onCreate()", "" );
int style = DialogFragment.STYLE_NO_TITLE;
int theme = getTheme();
setStyle( style, theme );
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
CLog.i("HelpDialog.onCreateDialog()", "" );
return super.onCreateDialog( savedInstanceState );
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
CLog.i("HelpDialog.onCreateView()", "" );
final View v = inflater.inflate( R.layout.help_dialog, container, false );
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
int screenHeight = displaymetrics.heightPixels;
int min_width = (displaymetrics.widthPixels * 70) / 100;
int min_height = (displaymetrics.heightPixels * 70) / 100;
v.setMinimumWidth( min_width );
//v.setMinimumHeight(min_height);
CLog.i( "HelpDialog.onCreateView()", "screenWidth " + screenWidth + " min_width " + min_width );
// Locate ViewPager in activity_main.xml
mPager = (ViewPager) v.findViewById( R.id.help_dlg_pager );
// Activate Fragment Manager
FragmentManager fm = this.getChildFragmentManager();//getActivity().getSupportFragmentManager();
// Capture ViewPager page swipes
ViewPager.SimpleOnPageChangeListener viewPagerListener = new ViewPager.SimpleOnPageChangeListener()
@Override
public void onPageSelected(int position)
super.onPageSelected(position);
;
mPager.setOnPageChangeListener( viewPagerListener );
// Locate the adapter class called ViewPagerAdapter.java
HelpDlgViewPagerAdapter viewpageradapter = new HelpDlgViewPagerAdapter(fm);
// Set the View Pager Adapter into ViewPager
mPager.setAdapter(viewpageradapter);
//mPager.setPageTransformer( true, new DepthPageTransformer() );
mPager.setPageTransformer( true, new ZoomOutPageTransformer() );
//Bind the title indicator to the adapter
CirclePageIndicator mIndicator = (CirclePageIndicator)v.findViewById( R.id.help_dlg_indicator );
mIndicator.setViewPager( mPager );
Button btn;
btn = (Button)v.findViewById( R.id.close_btn );
btn.setOnClickListener( new View.OnClickListener()
@Override
public void onClick( View view )
CLog.i( "HelpDialog", "onClick() - dismissing" );
dismissAllowingStateLoss();
);
getDialog().getWindow().setBackgroundDrawableResource( R.color.transparent );//translucent_black );
getDialog().getWindow().clearFlags( WindowManager.LayoutParams.FLAG_DIM_BEHIND );
getDialog().setCanceledOnTouchOutside( false );
return v;
////
@Override
public void onAttach ( Activity activity )
super.onAttach( activity );
CLog.i("HelpDialog.onAttach()", "" );
@Override
public void onActivityCreated (Bundle savedInstanceState)
super.onActivityCreated( savedInstanceState );
CLog.i("HelpDialog.onActivityCreated()", "" );
@Override
public void onViewStateRestored (Bundle savedInstanceState)
super.onViewStateRestored(savedInstanceState);
CLog.i("HelpDialog.onViewStateRestored()", "" );
@Override
public void onStart ()
super.onStart();
CLog.i("HelpDialog.onStart()", "" );
@Override
public void onStop ()
super.onStop();
CLog.i("HelpDialog.onStop()", "" );
@Override
public void onResume()
super.onResume();
CLog.i("HelpDialog.onResume()", "" );
@Override
public void onPause()
super.onPause();
CLog.i("HelpDialog.onPause()", "" );
@Override
public void onDestroyView()
super.onDestroyView();
CLog.i("HelpDialog.onDestroyView()", "" );
@Override
public void onDestroy ()
super.onDestroy();
CLog.i("HelpDialog.onDestroy()", "" );
@Override
public void onDetach ()
super.onDetach();
CLog.i("HelpDialog.onDetach()", "" );
【问题讨论】:
尽可能发布完整代码。 请看这可能对你有帮助:androiddesignpatterns.com/2013/08/… 查看此链接:hrupin.com/2013/05/… 我前段时间读过第一篇,我会再读一遍。当用户从应用程序菜单中选择“帮助”项时,将显示“帮助”对话框。当用户单击关闭按钮时,对话框关闭。我不明白为什么调用 onSaveInstanceState() 后对话框仍然存在(当对话框不应该存在时,用户可以单击关闭按钮)! 【参考方案1】:static boolean showNewInstance( FragmentActivity activity )
HelpDialog d = HelpDialog.newInstance();
if ( d != null )
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
Fragment prev = activity.getSupportFragmentManager().findFragmentByTag( HelpDialog.DIALOG_TAG );
if (prev != null)
ft.remove( prev );
// Create and show the dialog.
d.show( ft, HelpDialog.DIALOG_TAG );
return true;
return false;
您忘记提交事务。在ft.remove( prev );
之后添加这个:ft.commit();
【讨论】:
以上是关于当用户单击关闭按钮关闭 DialogFragment 时出现 IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章
iPhone:当用户单击主页按钮时,是不是可以关闭应用程序而不是在后台运行?