2017-06-22 116 views
3

我在我的android應用程序中使用了BottomBar菜單。 BottomBar有5個菜單。這是主要的活動活動狀態丟失,某些設備中出現非法狀態異常

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(); 
    } 
} 

標籤之間切換時(Bottombar菜單的),在一些設備應用程序崩潰的結果。但我無法重現異常。
這是堆棧跟蹤

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) 

誰能幫我!

回答

2

快速解決方案是用.commitAllowingStateLoss();代替。 commit();您正在爲當前活動執行的所有FragmentTransactions。

1

我面臨這個問題

我用.commitAllowingStateLoss();代替.commit();那些FragmentTransaction S的片段狀態有損失。

在另一類可以使用.commit();

2

有與其相關的錯誤:https://issuetracker.google.com/issues/36932872

要保存實例,並添加了一些你outState包,你可以使用以下命令:

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

也嘗試添加此行如果它不起作用:

transaction.commitAllowingStateLoss();