Android 当 运行 应用程序通过另一个应用程序时,无法在 saveInstanceState 之后执行此操作

Android can not perform this action after saveInstanceState when run app via another app

我有一个 Fragment,里面有 BroadcastReceiver,它包含在 Activity 中。 Activity 具有确定应用程序 link 的意图过滤器。在片段中进行一些操作后,我从服务器收到一封电子邮件,其中包含应用程序 link。因此,当我点击设备上的主页按钮时,应用程序不会破坏,并且当我在电子邮件中单击 link 时,必须打开一个新片段,但我有一个带有文本 Can not perform this action after saveInstanceState 的 IllegalStateException。如何解决?下面我附上了我的 activity 和两个片段代码:

public class PerfectoActivity extends AppCompatActivity implements ProgressUpdater, AuthFragment.ProgressActivator {

    @Bind(R.id.sign_up_progress) ProgressBar mSignUpProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_perfecto);
        ButterKnife.bind(this);
        if (cameFromMail()) {
            if (isSignUpProcess()) {
                mSignUpProgressBar.setVisibility(View.VISIBLE);
                String login = Utils.getLogin(this);
                String password = Utils.getPassword(this);
                String username = Utils.getUsername(this);
                String phone = Utils.getPhone(this);
                Utils.removePasswordAndPhone(this);
                ApiService.startActionAuth(this, login, password);
                getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, SignUpThirdStepFragment.newInstance(username, phone)).commit();
            } else {
                String login = Utils.getLogin(this);
                String resetCode = Utils.getResetCode(this);
                ApiService.startActionCheckConfirmReset(this, login, resetCode);
                getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, ResetPasswordFourthStepFragment.newInstance(login, resetCode)).commit();
            }
        } else {
            Utils.removePasswordAndPhone(this);
            getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new AuthFragment()).commit();
        }
    }

    private boolean isSignUpProcess() {
        Intent intent = getIntent();
        if (intent.getData() != null) {
            if (intent.getData().getLastPathSegment().equals("confirmreset")) {
                return false;
            }
            return true;
        }
        return false;
    }

    private boolean cameFromMail() {
        Intent intent = getIntent();
        if (intent.getData() != null)
        if (Intent.ACTION_VIEW.equals(intent.getAction())) return true;
        return false;
    }

    @Override
    public void updateProgress(int progress) {
        mSignUpProgressBar.setProgress(progress);
    }

    @Override
    public void activateProgress() {
        if (mSignUpProgressBar.getVisibility() == View.VISIBLE) {
            mSignUpProgressBar.setVisibility(View.GONE);
        }
        else {
            mSignUpProgressBar.setVisibility(View.VISIBLE);
        }
    }
}

这是第一个片段

public class ResetPasswordSecondStepFragment extends Fragment {


    private static final String BUNDLE_LOGIN = "com.rcd.perfecto.fragments.ResetPasswordSecondStep.bundle.LOGIN";
    public static final String RESET_PASSWORD_FILTER = "com.rcd.perfecto.fragments.filter.RESET_PASSWORD";

    private String mLogin;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
            if (!intent.getBooleanExtra(ApiService.EXTRA_SUCCESS, false)) {
                mPhoneErrorTextView.setVisibility(View.VISIBLE);
                mPhoneErrorTextView.setText(intent.getStringExtra(ApiService.EXTRA_MESSAGE));
            } else {
                String phone = mLastDigitsEditText.getText().toString();
                String resetCode = intent.getStringExtra(ApiService.EXTRA_DATA);
                FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.fragment_container, ResetPasswordThirdStepFragment.newInstance(mLogin, phone, resetCode)).commit();
            }
        }
    };

    @Bind(R.id.et_last_digits) EditText mLastDigitsEditText;
    @Bind(R.id.tv_phone_error) TextView mPhoneErrorTextView;

    @OnTextChanged(R.id.et_last_digits)
    void resetPassword(CharSequence digits) {
        if (digits.length() == 4) ApiService.startActionResetPassword(getActivity(), mLogin, mLastDigitsEditText.getText().toString());
    }

    public ResetPasswordSecondStepFragment() {
        // Required empty public constructor
    }

    public static ResetPasswordSecondStepFragment newInstance(String login) {
        ResetPasswordSecondStepFragment fragment = new ResetPasswordSecondStepFragment();
        Bundle args = new Bundle();
        args.putString(BUNDLE_LOGIN, login);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            mLogin =  args.getString(BUNDLE_LOGIN);
        }
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mReceiver, new IntentFilter(RESET_PASSWORD_FILTER));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_reset_password_second_step, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onDestroy() {
       super.onDestroy();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mReceiver);
    }
}

最后一个

public class ResetPasswordThirdStepFragment extends Fragment {

    private static final String BUNDLE_LOGIN = "com.rcd.perfecto.fragments.bundle.LOGIN";
    private static final String BUNDLE_RESET_CODE = "com.rcd.perfecto.fragments.bundle.RESET_CODE";
    private static final String BUNDLE_PHONE = "com.rcd.perfecto.fragments.bundle.PHONE";

    public static final String CHECK_CONFIRM_RESET_FILTER = "com.rcd.perfecto.fragments.filters.CHECK_CONFIRM_RESET";

    private String mResetCode;
    private String mLogin;
    private String mPhone;

    private BroadcastReceiver mConfirmReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getBooleanExtra(ApiService.EXTRA_SUCCESS, false)) {
                Utils.showAlert(R.string.reset_password_error, intent.getStringExtra(ApiService.EXTRA_MESSAGE), getActivity());
            } else {
                if (intent.getBooleanExtra(ApiService.EXTRA_DATA, false)) {
                     FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
                    transaction.replace(R.id.fragment_container, ResetPasswordFourthStepFragment.newInstance(mLogin, mResetCode)).commit();
                } else {
                    Utils.showAlert(R.string.reset_password_error, getResources().getString(R.string.reset_password_error_desc), getActivity());
               }
            }
        }
    };

    private BroadcastReceiver mSendConfirmationReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getBooleanExtra(ApiService.EXTRA_SUCCESS, false)) {
                Utils.showAlert(R.string.reset_password_error, intent.getStringExtra(ApiService.EXTRA_MESSAGE), getActivity());
            } else {
                mResetCode = intent.getStringExtra(ApiService.EXTRA_DATA);
                Utils.showAlert(R.string.sign_up_confirmation_link_title, getResources().getString(R.string.sign_up_confirmation_link), getActivity());
            }
        }
    };

    @Bind(R.id.btn_continue) Button mContinueButton;
    @Bind(R.id.tv_not_got_email) TextView mNotGotMailTextView;

    @OnClick(R.id.btn_continue)
    void confirmResetting() {
        ApiService.startActionCheckConfirmReset(getActivity(), mLogin, mResetCode);
    }

    @OnClick(R.id.tv_not_got_email)
    void sendConfirmationAgaing() {
        ApiService.startActionResetPassword(getActivity(), mLogin, mPhone);
    }

    public ResetPasswordThirdStepFragment() {
        // Required empty public constructor
    }

    public static ResetPasswordThirdStepFragment newInstance(String login, String phone, String resetCode) {
        ResetPasswordThirdStepFragment fragment = new ResetPasswordThirdStepFragment();
        Bundle args = new Bundle();
        args.putString(BUNDLE_LOGIN, login);
        args.putString(BUNDLE_PHONE, phone);
        args.putString(BUNDLE_RESET_CODE, resetCode);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
           mLogin = args.getString(BUNDLE_LOGIN);
           mPhone = args.getString(BUNDLE_PHONE);
           mResetCode = args.getString(BUNDLE_RESET_CODE);
           Utils.saveLogin(getActivity(), mLogin);
           Utils.savePhone(getActivity(), mPhone);
           Utils.saveResetCode(getActivity(), mResetCode);
        }
          LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mConfirmReceiver, new IntentFilter(CHECK_CONFIRM_RESET_FILTER));
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mSendConfirmationReceiver, new IntentFilter(ResetPasswordSecondStepFragment.RESET_PASSWORD_FILTER));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_reset_password_third_step, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mConfirmReceiver);
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mSendConfirmationReceiver);
    }
}

我看到您正在 BroadcastReceivers 中执行一些片段事务,因此可以在 activity 暂停且 onSaveInstanceState 已被调用时执行这些操作。 尝试使用 FragmentTransaction.commitAllowingStateLoss() 而不是简单的 FragmentTransaction.commit();