3. 多 Activity 跳转与 Intent 传参
显式 Intent 跳转与 Parcelable 传参的完整链路
本例在已有工程中新增一个 DetailActivity,由 MainActivity 通过显式 Intent 启动,并携带三类数据:基本类型(String、int)、Parcelable 对象、以及用于回传结果的请求码。目标页解析展示后,通过 setResult 把处理结果回传给调用方。
1. 定义可传递的 Parcelable 对象
Android 推荐用 Parcelable 在 Activity 间传递结构化对象,比 Serializable 更快。下面是一个最小可用的 User 类,包含姓名、年龄、是否 VIP 三个字段。
package com.example.intentdemo;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
private String name;
private int age;
private boolean vip;
public User(String name, int age, boolean vip) {
this.name = name;
this.age = age;
this.vip = vip;
}
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
vip = in.readByte() != 0;
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeByte((byte) (vip ? 1 : 0));
}
public String getName() { return name; }
public int getAge() { return age; }
public boolean isVip() { return vip; }
}
写入与读取顺序必须严格一致:
writeString → writeInt → writeByte 对应 readString → readInt → readByte,顺序错位会导致字段值串位。2. MainActivity 发起跳转并传参
使用显式 Intent 指定目标类,通过 putExtra 写入基本类型与 Parcelable 对象,再用 startActivityForResult 携带请求码启动,以便接收返回结果。
package com.example.intentdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_DETAIL = 1001;
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
Button btnOpen = findViewById(R.id.btn_open_detail);
btnOpen.setOnClickListener(v -> {
User user = new User("张三", 28, true);
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("extra_title", "用户详情页");
intent.putExtra("extra_count", 3);
intent.putExtra("extra_user", user);
startActivityForResult(intent, REQUEST_DETAIL);
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_DETAIL && resultCode == Activity.RESULT_OK && data != null) {
String feedback = data.getStringExtra("extra_feedback");
tvResult.setText("返回结果:" + feedback);
}
}
}
3. DetailActivity 解析展示并回传结果
目标页从 getIntent() 取出数据,注意 Parcelable 的读取方式与基本类型不同,需要指定 CREATOR。点击按钮后通过 setResult 回传结果并结束自身。
package com.example.intentdemo;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
TextView tvTitle = findViewById(R.id.tv_title);
TextView tvCount = findViewById(R.id.tv_count);
TextView tvUser = findViewById(R.id.tv_user);
Button btnBack = findViewById(R.id.btn_back);
Intent intent = getIntent();
String title = intent.getStringExtra("extra_title");
int count = intent.getIntExtra("extra_count", 0);
User user;
if (Build.VERSION.SDK_INT >= 33) {
user = intent.getParcelableExtra("extra_user", User.class);
} else {
user = intent.getParcelableExtra("extra_user");
}
tvTitle.setText(title);
tvCount.setText("数量:" + count);
if (user != null) {
tvUser.setText("姓名:" + user.getName()
+ ",年龄:" + user.getAge()
+ ",VIP:" + user.isVip());
}
btnBack.setOnClickListener(v -> {
Intent result = new Intent();
result.putExtra("extra_feedback", "已确认 " + (user != null ? user.getName() : ""));
setResult(RESULT_OK, result);
finish();
});
}
}
Android 13(API 33)起
getParcelableExtra(String) 已废弃,需使用带 Class 参数的重载;低版本仍用旧方法,因此上面做了版本分支。4. 注册 Activity 与传参链路
新增的 DetailActivity 必须在 AndroidManifest.xml 中注册,否则启动时会抛出 ActivityNotFoundException。
<activity android:name=".DetailActivity"
android:exported="false" />
5. 验证与结果判断
- 点击按钮后应跳转到
DetailActivity,页面显示标题“用户详情页”、数量 3、以及“姓名:张三,年龄:28,VIP:true”。 - 点击返回按钮后回到
MainActivity,结果文本应显示“返回结果:已确认 张三”。 - 若目标页显示
null,优先检查 key 是否拼写一致、Parcelable 读写顺序是否匹配。 - 若启动即崩溃并提示
ActivityNotFoundException,检查 Manifest 是否注册了DetailActivity。