06-07 02:45:20.344 E/AndroidRuntime( 2882): FATAL EXCEPTION: main
06-07 02:45:20.344 E/AndroidRuntime( 2882): java.lang.IllegalStateException: Failure saving state: ErrorDialog{41461640 #1 ErrorDialog} has target not in fragment manager: AccountCheckSettingsFragment{41461088}
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1609)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.Activity.onSaveInstanceState(Activity.java:1202)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at com.android.email.activity.setup.AccountSetupActivity.onSaveInstanceState(AccountSetupActivity.java:41)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.Activity.performSaveInstanceState(Activity.java:1150)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1215)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3007)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3066)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.ActivityThread.access$900(ActivityThread.java:134)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1230)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.os.Handler.dispatchMessage(Handler.java:99)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.os.Looper.loop(Looper.java:137)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at android.app.ActivityThread.main(ActivityThread.java:4830)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at java.lang.reflect.Method.invokeNative(Native Method)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at java.lang.reflect.Method.invoke(Method.java:511)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
06-07 02:45:20.344 E/AndroidRuntime( 2882):  at dalvik.system.NativeStart.main(Native Method)
06-07 02:45:20.354 W/ActivityManager(  310):   Force finishing activity com.android.email/.activity.setup.AccountSetupOptions
以上异常信息,我在网上查找有 但是却没有给出解决方案 很是苦恼私下也去看了onSaveInstanceState被调用说明的官方api 但是确实不知道如何修改我跟踪到AccountSetupActivity.java的41行 调用的super.onSaveInstanceState(outState);并且查看了framework层的 
android.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1609)
android.app.Activity.onSaveInstanceState(Activity.java:1202)这两个类  均是Google原生代码 无改动啊
public class AccountSetupActivity extends Activity {
    private static final boolean DEBUG_SETUP_FLOWS = false;  // Don't check in set to true    @Override
    public void onCreate(Bundle savedInstanceState) {
        SetupData.restore(savedInstanceState);
        super.onCreate(savedInstanceState);
        if (DEBUG_SETUP_FLOWS) {
            Log.d(getClass().getName(), SetupData.debugString());
        }
    }    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);        SetupData.save(outState);
    }
}
求解决方案    及定位分析的原因  谢谢了     分数不够可以再加~Email异常

解决方案 »

  1.   

    悲催的  就没人鸟我的帖子  我自己初步定为了原因:
    异常日志信息如下:
    06-07 02:45:20.334 E/FragmentManager( 2882): Failure saving state: ErrorDialog{41461640 #1 ErrorDialog} has target not in fragment manager: AccountCheckSettingsFragment{41461088}
    06-07 02:45:20.334 E/FragmentManager( 2882):   Active Fragments in 4145d9d0:
    06-07 02:45:20.334 E/FragmentManager( 2882):     #0: null
    06-07 02:45:20.334 E/FragmentManager( 2882):     #1: ErrorDialog{41461640 #1 ErrorDialog}
    06-07 02:45:20.334 E/FragmentManager( 2882):       mFragmentId=#0 mContainerId=#0 mTag=ErrorDialog
    06-07 02:45:20.334 E/FragmentManager( 2882):       mState=4 mIndex=1 mWho=android:fragment:1 mBackStackNesting=0
    06-07 02:45:20.334 E/FragmentManager( 2882):       mAdded=true mRemoving=false mResumed=false mFromLayout=false mInLayout=false
    06-07 02:45:20.334 E/FragmentManager( 2882):       mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
    06-07 02:45:20.334 E/FragmentManager( 2882):       mRetainInstance=false mRetaining=false mUserVisibleHint=true
    06-07 02:45:20.334 E/FragmentManager( 2882):       mFragmentManager=FragmentManager{4145d9d0 in AccountSetupBasics{4145d8a8}}
    06-07 02:45:20.334 E/FragmentManager( 2882):       mActivity=com.android.email.activity.setup.AccountSetupBasics@4145d8a8
    06-07 02:45:20.334 E/FragmentManager( 2882):       mArguments=Bundle[{ErrorDialog.Message=无法连接到服务器。, ErrorDialog.ExceptionId=1}]
    06-07 02:45:20.334 E/FragmentManager( 2882):       mTarget=AccountCheckSettingsFragment{41461088} mTargetRequestCode=0
    提示说明ErrorDialog未与指定的FragmentManager绑定【AccountCheckSettingsFragment】而在packages\apps\Email\src\com\android\email\activity\setup\AccountCheckSettingsFragment.java中绑定ErrorDialog的代码如下                    FragmentManager fm = getFragmentManager();
                        ......
                        if (fm.findFragmentByTag(ErrorDialog.TAG) == null) {
                            ErrorDialog errorDialog = ErrorDialog.newInstance(
                                    getActivity(), this, mProgressException);
                            fm.beginTransaction()
                                    .add(errorDialog, ErrorDialog.TAG)
                                    .commit();
                        }以上代码只是从FragmentManager 中去检测ErrorDialog.TAG 来判别ErrorDialog 是否存在 ,如果不存在,则添加ErrorDialog 的实例。代码如下:
            public static ErrorDialog newInstance(Context context, AccountCheckSettingsFragment target,
                    MessagingException ex) {
                ErrorDialog fragment = new ErrorDialog();
                Bundle arguments = new Bundle();
                arguments.putString(ARGS_MESSAGE, getErrorString(context, ex));
                arguments.putInt(ARGS_EXCEPTION_ID, ex.getExceptionType());
                fragment.setArguments(arguments);
                fragment.setTargetFragment(target, 0);
                return fragment;
            }而ErrorDialog 的实例却依赖于AccountCheckSettingsFragment用户在配置邮箱信息执行Next操作时,会事先弹出检测邮箱服务器外发设置及服务器接收设置信息的Dailog、此时用户再按Home键切换到后台运行检查,中途检测时,意外断网或者网络不好的情况下会弹出ErrorDialog ,一旦出现ErrorDialog 依赖 的AccountCheckSettingsFragment 不存在的情况下【这里我们无法知道AccountCheckSettingsFragment 何时会系统被销毁】,执行绑定到FragmentManager的操作会出现以上异常。处理意见 * 在执行绑定操作时,事先判别AccountCheckSettingsFragment 在FragmentManager中查找是否存在,如果存在 则执行绑定ErrorDialog 
                        Fragment tempFm = fm.findFragmentById(this.getId());                     if ((tempFm != null) && (fm.findFragmentByTag(ErrorDialog.TAG) == null)) {
                        ......红色部分为添加代码
      

  2.   

    那你有没有想过为什么tempFm 偶尔会为null呢?
      

  3.   

    进入Email输入账户密码下一步选择exchange进入exchange接收服务器参数配置界面后,点击下一步按钮后迅速点击上一步按钮,界面会卡在服务器参数检查的转圈对话框界面(不主动取消将一直停留在该界面),此时点击home键将必现Email crash,分析如下:
    1).exchange接收服务器配置界面,点击下一步后应用将向当前activity(AccountSetupExchange)安装无界面透明的账户检查fragment(AccountCheckSettingsFragment);该处理以FragmentTransaction事务形式添加,并将该事务压入目标activity的FragmentManager的后退栈中以便于用户点击back键后执行事务回滚
    2).AccountCheckSettingsFragment安装后执行账户检查异常任务,该异常任务处理中将向前台抛出参数检查转圈对话框CheckingDialog示意用户参数检查情况;异步任务后台线程处理结束后将结果抛到UI主线程并随之销毁CheckingDialog
    3).而在系统响应“下一步”按键启动异步任务后台处理过程中(大致100ms左右,此时CheckingDialog已安装显示),极限操作快速点击“上一步”系统响应该事件,即执行当前activity的“back”键处理,这将对activity属下的FragmentManager的后退栈做一次pop处理(移除之前压入该栈中的AccountCheckSettingsFragment事务),即卸载销毁AccountCheckSettingsFragment;与此同时,AccountCheckSettingsFragment销毁意味着账户检查结束,这将取消账户检查异常任务
    4).此时即造成了异常场景:AccountCheckSettingsFragment被销毁,账户检查异常任务被取消进而导致靠异步任务post结果进行销毁CheckingDialog的流程无法执行;此时按下“home”键后将触发activity的onSaveInstanceState保存其上各种信息如fragments各种参数,进而与该activity对应的FragmentManager检查fragment数据异常:CheckingDialog存活,但是CheckingDialog的target fragment即 AccountCheckSettingsFragment已消失,抛出异常IllegalStateExceptiontempFm 偶尔为null上述场景为其一,此处POP/IMAP/Exchange类似,ErrorDialog和CheckingDialog类似,保护的话可在AccountCheckSettingsFragment的onDestroy中增加dialog的dismiss、创建dialog的地方增加tempFm的判断