Android 如何修复:启动的活动完成时,onResume在onActivityResult之前和之后都被调用

Android 如何修复:启动的活动完成时,onResume在onActivityResult之前和之后都被调用,android,fragment,onactivityresult,onresume,fragment-lifecycle,Android,Fragment,Onactivityresult,Onresume,Fragment Lifecycle,我正在尝试使用调用活动 startActivityForResult() 从一块碎片上。这个活动基本上做了一些事情,然后返回结果,但是发生了什么,这真的很奇怪,在被调用的活动完成后,片段调用onStart,然后onResume,然后onActivityResult,然后再次onResume,我不明白为什么。这引起了很多麻烦 代码如下: Class extends ListFragment { ... @Override public void onResume() {

我正在尝试使用调用活动

startActivityForResult()
从一块碎片上。这个活动基本上做了一些事情,然后返回结果,但是发生了什么,这真的很奇怪,在被调用的活动完成后,片段调用onStart,然后onResume,然后onActivityResult,然后再次onResume,我不明白为什么。这引起了很多麻烦

代码如下:


Class extends ListFragment {
...
@Override
    public void onResume() {

        Log.i(TAG_LOG, "onResume");

        SharedPreferences pref = getActivity().getSharedPreferences(PreferenceKeys.PREF_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();

        long timePassed;

        // goes here if the trial time has expired
        if ((pref.getBoolean(PreferenceKeys.TRIAL_DONE, false) && pref.getString(PreferenceKeys.USERNAME, "").equals("")) ||
                (!pref.getBoolean(PreferenceKeys.TRIAL, false) && pref.getString(PreferenceKeys.USERNAME, "").equals(""))) {

            Log.i(TAG_LOG, "onResume-first if");

            if (pref.getBoolean(PreferenceKeys.ON_RESUME_CALL, true)) {

                Log.i(TAG_LOG, "onResume-first if-onResumeCall");
                editor.putBoolean(PreferenceKeys.ON_RESUME_CALL, false);

                Intent intent = new Intent(getActivity(), LoginRegisterActivity.class);
                if (!pref.getBoolean(PreferenceKeys.TRIAL_DONE, false)) {
                    intent.putExtra("showTrialButton", true);
                }
                startActivityForResult(intent, REQUEST_LOGIN_REGISTER);
            }
        } else if (!pref.getBoolean(PreferenceKeys.TRIAL_DONE, false) &&
                mResponseReceiver == null &&
                (timePassed  = pref.getLong(PreferenceKeys.TRIAL_STARTING_TIME, 0)) != 0) {


            Log.i(TAG_LOG, "sono dentroooooo");

            //this happens when the application has been force stopped,
            //since the receiver would never be notified and the trial would never end
             if ((System.currentTimeMillis() - timePassed) >= (30 * 60 * 1000)) {


                if (onUserActionListener != null) {
                    onUserActionListener.onTrialEnded();
                }

            } else {

                 if (onUserActionListener != null) {
                     onUserActionListener.onTrialStarted();
                 }
             }
        }
super.onResume();
}
...
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.i(TAG_LOG, "onActivityResult");

        if (requestCode == REQUEST_LOGIN_REGISTER) {
            if(resultCode == Activity.RESULT_OK){

                String username;
                String password;

                SharedPreferences preferences = getActivity().getSharedPreferences(PreferenceKeys.PREF_NAME, MODE_PRIVATE);
                SharedPreferences.Editor editor = preferences.edit();

                if ((!data.hasExtra(PreferenceKeys.USERNAME))) {
                    if(data.getBooleanExtra(PreferenceKeys.TRIAL, false) &&
                            !preferences.getBoolean(PreferenceKeys.TRIAL, false)) {

                        editor.putBoolean(PreferenceKeys.ON_RESUME_CALL, true).apply();

                        // this is used to show the log in button while mode is trial
                        onUserActionListener.onTrialStarted();

                    }
                } else {

                    // TODO: manage the connection with the server

                    username = data.getStringExtra(PreferenceKeys.USERNAME);
                    password = data.getStringExtra(PreferenceKeys.PASSWORD);


                    onUserActionListener.onUserConnected(username, password);

                }
            }
            if (resultCode == Activity.RESULT_CANCELED) {
                //Write your code if there's no result
            }
        }
    }
...
}

public class LoginRegisterActivity extends Activity {

    private Button trialButton;

    public static final int REQUEST_CODE_REGISTER = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_register);

        final Intent intent = new Intent();


        if (getIntent().hasExtra("showTrialButton") && getIntent().getExtras().getBoolean("showTrialButton")) {

            findViewById(R.id.trial_button).setVisibility(View.VISIBLE);

        }


        trialButton = findViewById(R.id.trial_button);
        trialButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                intent.putExtra(PreferenceKeys.TRIAL, true);
                setResult(RESULT_OK, intent);
                finish();
            }
        });
    }


}
这是日志打印的内容

启动 恢复 先恢复 if onResume首先if onResume调用 onActivityResult 恢复


我就是不明白。有人知道如何解决这个问题吗?

如果是这样的话,就让它去吧,不要弄乱操作系统,只是为了停止制造问题,你可以像这样为结果数据制作一个包装器:

public class MyDataWrapper<T> {
    private T t;
    private boolean dataHandled = false;

    public MyDataWrapper(){}

    public MyDataWrapper(T t){
        this.t = t;
    }

    public T getData(){
        dataHandled = true;
        return t;
    }

    public void setData(T t){
        if(this.t != t){
            this.t = t;
            dataHandled = false
        }
    }

    public boolean isDataHandled(){
        return dataHandled;
    }
}
class MyFragment extends ListFragment {

    private MyDataWrapper<MyData> myDataWrapper = new MyDataWrapper<>();

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data){
        if (/* all conditions are right */){
            myDataWrapper.setData(/* the data */);
        }
    }
    @Override
    public void onResume(){
        if (!myDataWrapper.isDataHandled()){
            // do the work
        } else {
            // data handled so there is no need to handle it again
        }
    }
}
公共类MyDataWrapper{
私人T;
私有布尔dataHandled=false;
公共MyDataWrapper(){}
公共MyDataWrapper(T){
t=t;
}
公共T getData(){
dataHandled=true;
返回t;
}
公共无效设置数据(T){
if(this.t!=t){
t=t;
dataHandled=false
}
}
公共布尔值isDataHandled(){
已处理的返回数据;
}
}
在你的片段中,你可以这样做:

public class MyDataWrapper<T> {
    private T t;
    private boolean dataHandled = false;

    public MyDataWrapper(){}

    public MyDataWrapper(T t){
        this.t = t;
    }

    public T getData(){
        dataHandled = true;
        return t;
    }

    public void setData(T t){
        if(this.t != t){
            this.t = t;
            dataHandled = false
        }
    }

    public boolean isDataHandled(){
        return dataHandled;
    }
}
class MyFragment extends ListFragment {

    private MyDataWrapper<MyData> myDataWrapper = new MyDataWrapper<>();

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data){
        if (/* all conditions are right */){
            myDataWrapper.setData(/* the data */);
        }
    }
    @Override
    public void onResume(){
        if (!myDataWrapper.isDataHandled()){
            // do the work
        } else {
            // data handled so there is no need to handle it again
        }
    }
}
类MyFragment扩展了ListFragment{ 私有MyDataWrapper MyDataWrapper=新MyDataWrapper(); @凌驾 ActivityResult上的公共void(int请求代码、int结果代码、意图数据){ 如果(/*所有条件都正确*/){ setData(/*数据*/); } } @凌驾 恢复时公开作废(){ 如果(!myDataWrapper.isDataHandled()){ //做这项工作 }否则{ //已处理数据,因此无需再次处理 } } }
如果您有两个片段,请尝试将hashCode()添加到日志中。尝试后,它会给出相同的hashCode,但感谢您的回复