Fragment中的setActivityForResult返回null数据

时间:2015-03-23 16:06:07

标签: java android android-fragments android-activity

我有一个片段MainFragment而且我这样做:

Intent i = new Intent(getActivity(), PersonActivity.class);
startActivityForResult(i, 0);

活动开始正常,它启动了自己的PersonFragment并在我PersonFragment内执行:

@Override
 public void onDestroy() {
      super.onDestroy();
      Intent i = new Intent();
      i.putExtra(PERSON_ID_EXTRA, getPersonId());
      i.putParcelableArrayListExtra(PERSON_CONTACT_LIST, (ArrayList<? extends Parcelable>) contactFriends);
      getActivity().setResult(Activity.RESULT_OK, i);
}

回到我的MainFragment我做:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if ( requestCode != 0) {
            return;
        }
        int personId = data.getIntExtra(PERSON_ID_EXTRA, -1);
        List<Person> contacts = data.getParcelableArrayListExtra(PERSON_CONTACT_LIST);
        for(Person p:contacts) {
            Log.d("APP", p.getFullName());
        }
}

我看到代码转到onActivityResult,但data为空。我在这里搞砸了什么?

更新
我看到按下后退按钮不会调用onDestroy() 但是我看到的所有例子都使用了getActivity.finish()并且我不想完成活动。仅当用户按下例如返回发送数据

UPDATE2:
我添加了以下内容并完成了该代码,但结果Intent data中的onActivityResult仍然为空

@Override
 public void onPause() {
      super.onPause();
      Intent i = new Intent();
      i.putExtra(PERSON_ID_EXTRA, getPersonId());
      i.putParcelableArrayListExtra(PERSON_CONTACT_LIST, (ArrayList<? extends Parcelable>) contactFriends);
      getActivity().setResult(Activity.RESULT_OK, i);
}

1 个答案:

答案 0 :(得分:2)

来自Activity documentation关于finish

  

在您的活动完成后调用此选项并应关闭。该   ActivityResult会传播回通过你发送给你的人   onActivityResult()。

来自documentation关于onActivityResult

  

当您启动的活动退出时调用,为您提供requestCode   你开始使用它返回的resultCode,以及任何其他的   来自它的数据。

因此,只有在第二个活动结束时才会调用onActivityResult

如果您不希望finish您的PersonActivity将结果发送到您的主要活动,那么您可能希望启动另一个意图来发送数据或使用静态字段传递数据(根本不是最佳做法。

在您的情况下,要在按下后退按钮时设置结果,您可以编写如下代码:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            Intent i = new Intent();
            i.putExtra(PERSON_ID_EXTRA, getPersonId());
            i.putParcelableArrayListExtra(PERSON_CONTACT_LIST, (ArrayList<? extends Parcelable>) contactFriends);
            getActivity().setResult(Activity.RESULT_OK, i);
            finish();
            return true;
    }
    return false;
}

根据评论进行跟进:

finish()Activity的代码如下所示:

// Call this when your activity is done
// and should be closed. The ActivityResult
// is propagated back to whoever launched
// you via onActivityResult().
public void finish() {
    if (mParent == null) {
        int resultCode;
        Intent resultData;
        synchronized (this) {
            resultCode = mResultCode;
            resultData = mResultData;
        }
        if (false) Log.v(TAG, "Finishing self: token=" + mToken);
        try {
            if (resultData != null) {
                resultData.prepareToLeaveProcess();
            }
            if (ActivityManagerNative.getDefault()
                .finishActivity(mToken, resultCode, resultData)) {
                mFinished = true;
            }
        } catch (RemoteException e) {
            // Empty
        }
    } else {
        mParent.finishFromChild(this);
    }
}

在这里,您可以看到设置结果值的责任在于finish()方法。

然后,在Activity被销毁之前,调用onDestroy()方法。这就是为什么在Activity方法上设置onDestroy()的结果不起作用的原因。