getting exception “IllegalStateException: Can not perform this action after onSaveInstanceState”

前端 未结 30 2098
迷失自我
迷失自我 2020-11-22 05:12

I have a Live Android application, and from market i have received following stack trace and i have no idea why its happening as its not happening in application code but it

相关标签:
30条回答
  • 2020-11-22 05:41

    Same issue from me and after a day long analysis of all articles, blog and stackoverflow i've found a simple solution. Don't use savedInstanceState at all, this is the condition with one line of code. On the fragment code:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);
        .....
    
    0 讨论(0)
  • 2020-11-22 05:43

    Thanks @gunar, but I think there is a better way.

    According to doc :

     * If you are committing a single transaction that does not modify the
     * fragment back stack, strongly consider using
     * {@link FragmentTransaction#commitNow()} instead. This can help avoid
     * unwanted side effects when other code in your app has pending committed
     * transactions that expect different timing.
     *
     * @return Returns true if there were any pending transactions to be
     * executed.
     */
    public abstract boolean executePendingTransactions();
    

    So use commitNow to replace:

    fragmentTransaction.commit();
    FragmentManager.executePendingTransactions()
    
    0 讨论(0)
  • 2020-11-22 05:43

    you can use FragmentActivity.onStart before popBackStackImmediate

    like this:

    public void backStackFragment() {
        this.start();
        getFragmentManager().popBackStackImmediate();
    }
    
    public void start(){
        FragmentActivity a = getActivity();
        if(a instanceof DepositPlanPadActivity){
          ((DepositPlanPadActivity)a).onStart();
        }
        if(a instanceof SmallChangePlanPad){
                ((SmallChangePlanPad)a).onStart();
            }
            if(a instanceof UserCenterActivity){
                ((UserCenterActivity)a).onStart();
            }
        }
    

    http://jorryliu.blogspot.com/2014/09/illegalstateexception-can-not-perform.html

    0 讨论(0)
  • 2020-11-22 05:45

    This can also happen when calling dismiss() on a dialog fragment after the screen has been locked\blanked and the Activity + dialog's instance state has been saved. To get around this call:

    dismissAllowingStateLoss()
    

    Literally every single time I'm dismissing a dialog i don't care about it's state anymore anyway, so this is ok to do - you're not actually losing any state.

    0 讨论(0)
  • 2020-11-22 05:45

    I solved the issue with onconfigurationchanged. The trick is that according to android activity life cycle, when you explicitly called an intent(camera intent, or any other one); the activity is paused and onsavedInstance is called in that case. When rotating the device to a different position other than the one during which the activity was active; doing fragment operations such as fragment commit causes Illegal state exception. There are lots of complains about it. It's something about android activity lifecycle management and proper method calls. To solve it I did this: 1-Override the onsavedInstance method of your activity, and determine the current screen orientation(portrait or landscape) then set your screen orientation to it before your activity is paused. that way the activity you lock the screen rotation for your activity in case it has been rotated by another one. 2-then , override onresume method of activity, and set your orientation mode now to sensor so that after onsaved method is called it will call one more time onconfiguration to deal with the rotation properly.

    You can copy/paste this code into your activity to deal with it:

    @Override
    protected void onSaveInstanceState(Bundle outState) {       
        super.onSaveInstanceState(outState);
    
        Toast.makeText(this, "Activity OnResume(): Lock Screen Orientation ", Toast.LENGTH_LONG).show();
        int orientation =this.getDisplayOrientation();
        //Lock the screen orientation to the current display orientation : Landscape or Potrait
        this.setRequestedOrientation(orientation);
    }
    
    //A method found in stackOverflow, don't remember the author, to determine the right screen orientation independently of the phone or tablet device 
    public int getDisplayOrientation() {
        Display getOrient = getWindowManager().getDefaultDisplay();
    
        int orientation = getOrient.getOrientation();
    
        // Sometimes you may get undefined orientation Value is 0
        // simple logic solves the problem compare the screen
        // X,Y Co-ordinates and determine the Orientation in such cases
        if (orientation == Configuration.ORIENTATION_UNDEFINED) {
            Configuration config = getResources().getConfiguration();
            orientation = config.orientation;
    
            if (orientation == Configuration.ORIENTATION_UNDEFINED) {
            // if height and widht of screen are equal then
            // it is square orientation
                if (getOrient.getWidth() == getOrient.getHeight()) {
                    orientation = Configuration.ORIENTATION_SQUARE;
                } else { //if widht is less than height than it is portrait
                    if (getOrient.getWidth() < getOrient.getHeight()) {
                        orientation = Configuration.ORIENTATION_PORTRAIT;
                    } else { // if it is not any of the above it will defineitly be landscape
                        orientation = Configuration.ORIENTATION_LANDSCAPE;
                    }
                }
            }
        }
        return orientation; // return value 1 is portrait and 2 is Landscape Mode
    }
    
    @Override
    public void onResume() {
        super.onResume();
        Toast.makeText(this, "Activity OnResume(): Unlock Screen Orientation ", Toast.LENGTH_LONG).show();
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
    } 
    
    0 讨论(0)
  • 2020-11-22 05:45

    I was getting this exception when I was pressing back button to cancel intent chooser on my map fragment activity. I resolved this by replacing the code of onResume()(where I was initializing the fragment and committing transaction) to onStart() and the app is working fine now. Hope it helps.

    0 讨论(0)
提交回复
热议问题