使用显式意图在两个活动之间发送数据

时间:2016-08-03 22:22:53

标签: java android android-intent

我有两个活动 - 活动A和活动B.在打开应用程序时,用户会看到活动A.

单击活动A上的按钮时,将打开活动B.

在活动B中,系统会提示用户将一些文本添加到EditText字段中,该字段存储在TextView对象中。

当您单击活动B上的按钮时,它会将您重定向到活动A,并将存储在TextView对象中的数据传递给活动A以显示在屏幕上。

我的假设逻辑:

活动A构造一个新的Intent并传入Activity B.

活动A调用startActivityForResult(intent)。

活动B然后调用getIntent(),但不执行任何操作,因为没有必要(?)

在onClick()方法中,活动B创建一个新的Intent,传入Activity A.活动B将其结果放入新的Intent(即使用intent.putExtra())

调用活动A中的 onActivityResult()。

我想知道,如果这是正确的逻辑吗?

3 个答案:

答案 0 :(得分:3)

是的,您正在按照您的预期完成工作。通过意图传递数据似乎有点奇怪,但这就是Android的设计方式。请记住,活动可能存在于不同的进程中,因此系统会对数据进行序列化和反序列化,以便执行进程间通信。意图机制是跨越它们交换信息的标准方式,这就是为什么意图只保存原始数据,Parcelables和Serializables。话虽这么说,一个意图交换的数据在双方都不是同一个实例,而是原始数据的实际副本。

答案 1 :(得分:0)

弗拉维奥提到你的逻辑看起来很好。只是想补充说,如果你不期望任何意图,你不必在Activity B中调用getIntent()。你可以避免这一行。

答案 2 :(得分:0)

不,这不是你应该怎么做的。

使用startActivityForResult()时,被调用的活动(在您的示例中为B)必须在setResult()之前使用:finish()。这是它为调用活动提供结果的方式。

从活动B开始,除非您需要一些参数或检查是否已经调用了结果,否则无需致电getIntent()

让我们举一个例子:FriendsActivity是一个旨在管理朋友的活动,它通常显示当前的朋友列表并允许添加更多。

从应用的某个位置,您需要用户选择朋友进行某些操作,因此您有一个按钮:选择朋友,其中FriendsActivity打开ACTION_PICKstartActivityForResult()

所有这些都是这样的:

Intent pickFriendIntent = new Intent(this, FriendsActivity.class);
pickFriendIntent.setAction(Intent.ACTION_PICK);
startActivityForResult(pickFriendIntent, REQUEST_PICK_FRIEND);

REQUEST_PICK_FRIEND是调用者活动中定义的常量int(如果您有多种类型的请求带有结果,则非常有用)。

来自FriendsActivity

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // boolean flag to know if we are requested to pick or not
    mPickMode = getIntent() != null && Intent.ACTION_PICK.equals(getIntent().getAction());
    // etc...
}

该标志让我们修改我们活动的行为来挑选朋友。

例如,当点击朋友时,我们应该返回朋友信息并完成活动,而不是转到他的个人资料(或之前使用过的任何操作),我们应该返回朋友信息并完成活动:

public void onFriendClicked(Friend theFriend) {
    if (mPickMode) {
        Intent resultData = new Intent();
        // assuming Friend is Parcelable, if not just pass an ID or something
        // it's usually best to handle this with a custom Uri actually
        resultData.putExtra("friendParcelable", theFriend);
        // here we set the result for the calling activity
        setResult(RESULT_FRIEND_PICKED, resultData);
        // and then we finish this one
        finish();
    } else { ... }
}

RESULT_FRIEND_PICKEDint常量,通常是公共的。它告诉父活动发生了哪种结果,你可以有多个,满足你的需求。实际上,在上面的例子中为"friendParcelable"创建额外的公共常量也是一个好主意。

FriendsActivity完成调用者后,获得回调:

protected void onActivityResult (int requestCode, 
            int resultCode, 
            Intent data) {
    if (requestCode == REQUEST_PICK_FRIEND) {
        if (resultCode == FriendsActivity.RESULT_FRIEND_PICKED) {
            Friend pickedFriend = data.getParcelableExtra("friendParcelable");
            // do whatever you want with that information
        } else if (resultCode == Activity.RESULT_CANCELED) {
            // the FriendsActivity terminated without calling setResult();
        }
    }
}

另请注意,finish()之后不必立即致电setResult()。如果您致电setResult()然后让用户点击它,它仍会提供结果。但是,如果在调用setResult()之后活动被销毁并重新创建(例如设备轮换),则必须再次致电setResult()