IllegalStateException: Cannot complete this action after onSaveInstanceState - Andorid

I'm trying to figure out why my android app crashes sometimes, with the above exception. I cannot find the source of the problem from what logcat says.

This rarely happens. I would be glad for any suggestion. Thank!

Logcat output:

java.lang.IllegalStateException: Unable to execute this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1360) in android.support.v4.app.FragmentManagerImpl.enquejueAager ( ) at android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java:595) at android.support.v4.app.BackStackRecord.commit (BackStackRecord.java:574) at android.support.v4.app.FragmentTabHost. onAttachedToWindow (FragmentTabHost.java:282) on android.view.View.dispatchAttachedToWindow (View.java:12752) on android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:2577) on android.view.ViewGroup.dispatchAttachedTachedTached : 2584) at android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:2584) at android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:2584) at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1427) at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1192) at android.view.ViewRootImpl $ TraversalRunnable.run (ViewRoot6231pl.java: android.view.Choreographer $ CallbackRecord.run (Choreographer.java:788) at android.view.Choreographer.doCallbacks (Choreographer .java: 591) at android.view.Choreographer.doFrame (Choreographer .java: 560) at android.view .Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:774) at android.os.Handler.handleCallback (Handler.java:808) at android.os.Handler.dispatchMessage (Handler.java:103) at android.os.Looper. loop (Looper.java:193) at android.app.ActivityThread.main (ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative (native method) at java.lang.reflect.Method.invoke (Method. java: 515) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:640) at dalvik.system.NativeStart.main (native method)

Primary activity:

public class MainActivity extends FragmentActivity {

    private FragmentTabHost mTabHost;    
    private UiLifecycleHelper uiHelper;

    LocationClient mClient;
    LocationRequest mRequest;
    private String user;
    private String userId;
    private ImageButton addPlaceBtn;
    private SQLiteDataSource datasource;
    private TextView notifTextView;
    private boolean appIsOn = false; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayShowTitleEnabled(false);
        setContentView(R.layout.activity_main);

        datasource = new SQLiteDataSource(this);
        datasource.open();

        uiHelper = new UiLifecycleHelper(this, null);
        uiHelper.onCreate(savedInstanceState);

        if (isFacebookLoggedIn()) {
            System.out.println("We are logged in!");
        } else {
            showLogin();
        }

        if (datasource.getAllImageItems().isEmpty()) {
            Intent splash = new Intent(this, SplashActivity.class);
            startActivity(splash);
        }

        addPlaceBtn = (ImageButton) findViewById(R.id.addPlace1);

        uiHelper = new UiLifecycleHelper(this, null);
        uiHelper.onCreate(savedInstanceState);

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(),
                android.R.id.tabcontent);

        mTabHost.addTab(
                mTabHost.newTabSpec("tab1").setIndicator("PREPARATE", null),
                OffersFragmentActivity.class, null);
        mTabHost.addTab(
                mTabHost.newTabSpec("tab2").setIndicator("CATEGORII", null),
                CategoriesActivity.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab3")
                .setIndicator("CAIETE", null), BooksFragmentActivity.class,
                null);

        for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
            mTabHost.getTabWidget().getChildAt(i)
                    .setBackgroundResource(R.drawable.tab_text_selector);
            mTabHost.getTabWidget().setDividerDrawable(R.drawable.divider);
            final TextView tv = (TextView) mTabHost.getTabWidget()
                    .getChildAt(i).findViewById(android.R.id.title);
            if (tv == null)
                continue;
            else
                tv.setTextColor(0xFFFFFFFF);
        }

        mTabHost.setOnTabChangedListener(new OnTabChangeListener() {

            public void onTabChanged(String tabId) {

                switch (mTabHost.getCurrentTab()) {
                case 0:
                    addPlaceBtn.setVisibility(View.VISIBLE);
                    break;
                case 1:
                    addPlaceBtn.setVisibility(View.GONE);
                    break;
                case 2:
                    addPlaceBtn.setVisibility(View.GONE);
                    break;

                default:

                    break;
                }
            }
        });

        addPlaceBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (user != null && isOnline()) {
                    Intent i = new Intent(getApplication(),
                            CameraActivity.class);
                    startActivity(i);
                } else if (user == null) {
                    // If user is not logged in, start login activity
                    Intent i = new Intent(getApplication(), LoginActivity.class);
                    startActivity(i);
                } else if (!isOnline()) {
                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                            MainActivity.this);
                    alertDialogBuilder.setTitle("Internetul este oprit");
                    alertDialogBuilder
                            .setMessage("Pentru actualizarea continutului aveti nevoie de internet. Porniti acum?");
                    alertDialogBuilder.setPositiveButton("Da",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // go to a new activity of the app
                                    Intent settingsIntent = new Intent(
                                            Settings.ACTION_DATA_ROAMING_SETTINGS);
                                    settingsIntent
                                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(settingsIntent);
                                    finish();
                                }
                            });
                    // set negative button: No message
                    alertDialogBuilder.setNegativeButton("Nu",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // cancel the alert box and put a Toast to
                                    // the user
                                    finish();
                                }
                            });

                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();
                }
            }
        });

        if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
            Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);        
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));

        final Menu m = menu;
        final MenuItem item = menu.findItem(R.id.action_notifications);
        View actionView = item.getActionView();
        notifTextView = (TextView) actionView.findViewById(R.id.notifTextView);

        String unreadNotifs = datasource.countUnreadNotif();
        if (!unreadNotifs.equals("0")) {
            notifTextView.setText(unreadNotifs);
        } else {
            notifTextView.setVisibility(View.GONE);
        }

        item.getActionView().setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                m.performIdentifierAction(item.getItemId(), 0);

            }
        });

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_user) {
            Intent i = new Intent(this, UserProfile.class);
            i.putExtra("user", user);
            i.putExtra("userId", userId);
            startActivity(i);

            return true;
        }

        if (id == R.id.action_notifications) {
            Intent i = new Intent(this, Notifications.class);
            startActivity(i);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private boolean isFacebookLoggedIn() {
        Session session = Session.getActiveSession();

        if (session != null) {
            // Session can be open, check for valid token
            if (!session.isClosed()) {
                if (!session.getAccessToken().equalsIgnoreCase("")) {
                    return true;
                }
            }
        }
        return false;
    }

    // FB Login Session and user info
    public void showLogin() {
        Intent i = new Intent(this, LoginActivity.class);
        startActivity(i);

    }

    @Override
    protected void onResume() {
        super.onResume();
        uiHelper.onResume();
        appIsOn = true;
        invalidateOptionsMenu();

        if (!isOnline()) {
            showGpsButton();
        }

        SharedPreferences preferences = getSharedPreferences("USERINFO",
                Context.MODE_PRIVATE);
        user = preferences.getString("name", null);
        userId = preferences.getString("userId", null);
        userId = preferences.getString("userId", null);

        GCMActivity gcm = new GCMActivity(this);
        gcm.registerIfNeeded();

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
        appIsOn = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
        datasource.deleteAllRows();

    }

    public void showGpsButton() {
        LinearLayout buttonLayout = (LinearLayout) findViewById(R.id.gpsWarning);
        buttonLayout.setVisibility(View.VISIBLE);
        buttonLayout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent settingsIntent = new Intent(
                        Settings.ACTION_DATA_ROAMING_SETTINGS);
                settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(settingsIntent);
                finish();
            }
        });
    }

    public boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected()) {
            return true;
        }
        return false;
    }

}

      

+3


source to share


1 answer


I experienced a similar issue with KitKat. But on Lollipop it works fine. Regardless, we have to support many OS versions, right? :)

The main reason is that starting a new activity causes it to MainActivity

pause before it finishes creating completely. When it pauses, it saves the state of the instance immediately. But since the instances Fragment

are committed in a weird end-of-main thread loop, the start-pause-save loop gets out of order, throwing this crash. And in some cases it can be a race condition and occur sporadically.

Here's the code that seems to fix it after re-testing it:



@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);

    Handler hanlder = new Handler();
    hanlder.post(new Runnable() {
        @Override
        public void run() {
            if (isFacebookLoggedIn()) {
                System.out.println("We are logged in!");
            } else {
                showLogin();
            }

            if (datasource.getAllImageItems().isEmpty()) {
                Intent splash = new Intent(MainActivity.this, SplashActivity.class);
                startActivity(splash);
            }
        }
    });
}

      

The trick is to create an event Handler

and dispatch to the end of the main thread to ensure that this happens after all instances Fragment

have been committed. Doing it in onPostCreate

, rather than immediately in onCreate

, should also help in this situation.

+1


source







All Articles