Loss of activity state, exception of conditional state in some devices

I am using BottomBar

menu in my android app. And there are 5 menus in BottomBar

. This is the main activity.

public class MainActivity extends BaseActivity {
    private static final String TAG = "MainActivity";
    private static final String COMMAND_RESET_PASSWORD = "reset-password";
    private static final String COMMAND_REFERRAL = "referral";
    private static final int HOME = 0;
    private static final int MAP = 1;
    private static final int DEAL = 2;
    private static final int NOTIFICATION = 3;
    private static final int SETTINGS = 4;
    private BottomBar mBottomBar;
    private int mCurrentTab = HOME;
    private BottomBarBadge mNotificationBadge;
    private boolean mActive;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mActive = true;
        super.onCreate(savedInstanceState);

        initBottomBar(savedInstanceState);
        Intent intent = getIntent();
        handleIntent(intent);
    }
    private void initBottomBar(Bundle savedInstanceState) {
        mBottomBar = BottomBar.attach(this, savedInstanceState);
        mBottomBar.useFixedMode();
        mBottomBar.noTabletGoodness();
        mBottomBar.setItemsFromMenu(R.menu.bottombar_menu, new OnMenuTabClickListener() {
        @Override
        public void onMenuTabSelected(@IdRes int menuItemId) {

            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

            switch (menuItemId) {

                case R.id.bottomBarHome:
                    showStoreList();
                    break;

                case R.id.bottomBarMap:
                    showMap();
                    break;

                case R.id.bottomBarDeal:
                    showDeals();
                    break;

                case R.id.bottomBarSettings:
                    showSettings();
                    break;
                case R.id.bottomBarNotification:
                    if (mNotificationBadge != null) {
                        mNotificationBadge.hide();
                        Sample.getApp().clearBadge();
                    }
                    showNotifications();
                    break;
            }
        }

        @Override
        public void onMenuTabReSelected(@IdRes int menuItemId) {
            switch (menuItemId) {
                case R.id.bottomBarHome:
                    if (mCurrentTab != HOME)
                        showStoreList();
                    break;

                case R.id.bottomBarMap:
                    if (mCurrentTab != MAP)
                        showMap();
                    break;

                case R.id.bottomBarDeal:
                    if (mCurrentTab != DEAL) {
                        showDeals();
                    }
                    break;

                case R.id.bottomBarNotification:
                    if(mCurrentTab != NOTIFICATION) {
                        if (mNotificationBadge != null) {
                            mNotificationBadge.hide();
                            mNotificationBadge.setDealItemCount(0);
                            Sample.getApp().clearBadge();
                        }
                        showNotifications();
                    }
                    break;

                case R.id.bottomBarSettings:
                    if (mCurrentTab != SETTINGS)
                        showSettings();
                    break;
            }
        }
        });

        mNotificationBadge = mBottomBar.makeBadgeForTabAt(3, R.color.sample_badge_color, Sample.getApp().getBadgeCount());
    }

    public void hideBottomBar() {
        if (mBottomBar != null) mBottomBar.hide();
    }
    public void showBottomBar() {
        if (mBottomBar != null) mBottomBar.show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        handleCommands();
        if (mNotificationBadge != null) {
        mNotificationBadge.setDealItemCount(Sample.getApp().getBadgeCount());
        }
    }


    public void showPointPopUp() {
        PointDialogFragment fragment = new PointDialogFragment();
        fragment.setShowsDialog(true);
        fragment.show(getSupportFragmentManager(),TAG);
    }

    private void showStoreList() {
        mCurrentTab = HOME;
        Fragment fragment = Fragment.instantiate(this, StoreListFragment.class.getName());
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commitAllowingStateLoss();
    }

    private void showMap() {
        String storeId = Sample.getApp().getMallId();
        Store store = mStoreCache.getMall(storeId);
        if (store != null && store.isMapAvailable()) {
        Bundle args = new Bundle();
        args.putString(Sample.EXTRA_STORE_ID, Sample.getApp().getMallId());
        args.putBoolean(Sample.EXTRA_COMMAND, true);
        Fragment fragment = Fragment.instantiate(this, SampleMapFragment.class.getName(), args);
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_frame, fragment)
                .commitAllowingStateLoss();
        } else {
        Fragment fragment = Fragment.instantiate(this, StoreMapFragment.class.getName());
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_frame, fragment)
                .commitAllowingStateLoss();

        }

        mCurrentTab = MAP;
    }

    private void showDeals() {
        mCurrentTab = DEAL;
        String storeId = Sample.getApp().getMallId();
        Bundle args = new Bundle();
        if (storeId != null)
        args.putString(Sample.EXTRA_STORE_ID, storeId);
        Fragment fragment = Fragment.instantiate(this, DealsFragment.class.getName(), args);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commitAllowingStateLoss();
    }

    private void  showNotifications(){
        mCurrentTab = NOTIFICATION;
        Fragment fragment = Fragment.instantiate(this, NotificationFragment.class.getName());
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commitAllowingStateLoss();
    }

    private void showSettings() {
        mCurrentTab = SETTINGS;
        Fragment fragment = Fragment.instantiate(this, ProfileFragment.class.getName());
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .commitAllowingStateLoss();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected int getLayoutResource() {
        return R.layout.activity_content_frame;
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        Log.d(TAG, "inside onNewIntent");
        if (mActive) {
        handleIntent(getIntent());
        }

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

    @Override
    protected void onDestroy() {
        mActive = false;
        super.onDestroy();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Branch branch = Branch.getInstance();
        if (BuildConfig.DEBUG) {
        branch.setDebug();
        }
        Log.d(TAG, "inside branch no error");
        branch.initSession((referringParams, error) -> {
        if (error == null) {
            try {
                Log.d(TAG, "parsed data from referringParams");
                if (referringParams.has("data")) {
                    String link = referringParams.getJSONObject("data").getString("link");
                    if(link != null && !link.isEmpty()){
                        Uri uri = Uri.parse(link);
                        if(uri.getScheme().equals("sample")){

                            List<String> pathSegments = uri.getPathSegments();

                            String command = "";
                            String argument = null;

                            if (!pathSegments.isEmpty() && pathSegments.size() == 1) {
                                command = uri.getHost();
                                argument = pathSegments.get(0);
                            }
                            if(COMMAND_REFERRAL.equals(command) && argument != null){
                                Sample.getApp().currentUser().setReferralCode(argument);
                            }else {
                                Intent activityIntent = new Intent(MainActivity.this, LinkHandlerActivity.class);
                                activityIntent.setData(uri);
                                startActivity(activityIntent);
                            }
                        }
                    }

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        }, this.getIntent().getData(), this);
    }

    public void showSignUpInPage() {/*line 319 */
        Bundle args = new Bundle();
        args.putString(Sample.TYPE, Sample.SIGN_UP);
        Fragment fragment =
            Fragment.instantiate(this, SignUpInFragmentMain.class.getName(),args);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .addToBackStack(null)
            .commit();/***This is the 319th line***/
    }

    public void forgotPassword(){
        Fragment fragment =
            Fragment.instantiate(this, ForgotPasswordFragment.class.getName());
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .addToBackStack(null)
            .commit();
    }

    private void handleCommands() {
        if (!mActive || Sample.getApp().getNotificationCommand() == null) {
        return;
        }
        switch (Sample.getApp().getNotificationCommand()) {
        case Sample.COMMAND_DEAL:
            showStoreDetail(Sample.getApp().getStoreId());
            break;
        case Sample.COMMAND_MALL_DEAL:
            showMallDetail(Sample.getApp().getStoreId());
            break;
        case Sample.COMMAND_REGISTER:
            showSignUpInPage();
            break;
        case Sample.COMMAND_DEFAULT:
            break;
        case Sample.COMMAND_MAP:
            mBottomBar.selectTabAtPosition(1, true);
            break;
        }
        Sample.getApp().setNotificationCommand(null);

    }

    private void handleIntent(Intent intent) {
        if (!mActive) {
        return;
        }
        Uri uri = intent.getData();
        if (uri != null) {
        Fragment fragment;
        List<String> pathSegments = uri.getPathSegments();

        String command;
        String argument;
        if (pathSegments.isEmpty()) {
            return;
        }
        if (pathSegments.size() == 1) {
            command = uri.getHost();
            argument = pathSegments.get(0);
        } else {
            command = pathSegments.get(1);
            argument = pathSegments.size() > 2 ? pathSegments.get(2) : null;
            Log.d(TAG,pathSegments.toString());
        }

        Bundle args = new Bundle();

        switch (command) {

            case COMMAND_RESET_PASSWORD:
                String uid = pathSegments.size() > 2 ? pathSegments.get(2) : null;
                String token = pathSegments.size() > 3 ? pathSegments.get(3) : null;
                args.putString(Sample.EXTRA_PASSWORD_TOKEN, token);
                args.putString(Sample.EXTRA_PASSWORD_UID, uid);
                Fragment resetPasswordFragment =
                        Fragment.instantiate(this, ResetPasswordFragment.class.getName(), args);
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.content_frame, resetPasswordFragment)
                        .addToBackStack(null)
                        .commit();
                break;

            case COMMAND_REFERRAL:
                if(argument != null)
                    Sample.getApp().currentUser().setReferralCode(argument);
                break;
        }
        }
    }

    private void showStoreDetail(String storeId) {
        Sample.getApp().setStoreId(null);
        Bundle args = new Bundle();
        args.putString(Sample.EXTRA_STORE_ID, storeId);
        Fragment fragment = Fragment.instantiate(this, StoreDetailFragment.class.getName(), args);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .addToBackStack(null)
            .commit();
    }

    private void showMallDetail(String storeId) {
        Sample.getApp().setStoreId(null);
        Bundle args = new Bundle();
        args.putString(Sample.EXTRA_STORE_ID, storeId);
        Fragment fragment = Fragment.instantiate(this, MallDetailFragment.class.getName(), args);
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, fragment)
            .addToBackStack(null)
            .commit();
    }
}

      

when switching between tabs (Bottombar menu) causes the application to crash on some devices. But I was unable to reproduce the exception.
This is the stacktrace

    Non-fatal Exception: java.lang.RuntimeException: Unable to resume activity {com.beco.ibeco/com.beco.ibeco.app.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3000)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3031)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5268)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
Caused by java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1842)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1860)
       at android.support.v4.app.FragmentManagerImpl.popBackStack(FragmentManager.java:781)
       at com.beco.ibeco.app.MainActivity$1.onMenuTabSelected(MainActivity.java:74)
       at com.beco.ibeco.app.views.bottombar.BottomBar.notifyMenuListener(BottomBar.java:1239)
       at com.beco.ibeco.app.views.bottombar.BottomBar.updateSelectedTab(BottomBar.java:1199)
       at com.beco.ibeco.app.views.bottombar.BottomBar.selectTabAtPosition(BottomBar.java:437)
       at com.beco.ibeco.app.MainActivity.handleCommands(MainActivity.java:347)
       at com.beco.ibeco.app.MainActivity.onResume(MainActivity.java:154)
       at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
       at android.app.Activity.performResume(Activity.java:6119)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2989)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3031)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5268)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)

      

Can someone help me.!

+3


source to share


3 answers


A quick solution is to use .commitAllowingStateLoss();

instead. commit();

for all the FragmentTransactions you do for the current activity.



+2


source


There is a bug related to it: https://issuetracker.google.com/issues/36932872

To save an instance and add something to your outState Bundle, you can use the following:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_KEY","WORKAROUND_FOR_BUG_VALUE");
    super.onSaveInstanceState(outState);
}

      



Also try adding this line if it doesn't work:

transaction.commitAllowingStateLoss();

      

+2


source


I faced this problem

I use .commitAllowingStateLoss();

instead .commit();

for those FragmentTransaction

whose fragment state has a loss.

In another class, you can use .commit();

+1


source







All Articles