
刚学Android开发时,最头疼的就是Activity间传参——明明在第一个页面放了参数,第二个页面却拿不到,要么报空指针,要么拿到的是默认值。后来才发现,Intent传参有很多“隐性规则”,比如静态变量要注意生命周期,Bundle传参要对应数据类型。今天就把Android中Activity间传参的4种常用方式拆解开,附完整代码和避坑点,新手也能跟着做。
在Android中,每个Activity都是独立的页面容器,比如“登录页”要把用户输入的账号传给“主页”,“商品列表页”要把选中的商品ID传给“商品详情页”——这些都需要通过Intent(意图)来实现。
Intent就像“信使”,负责在Activity之间传递“请求动作”和“附加数据”,它的核心作用是:
另外,Activity间跳转分两种场景,传参方式也会对应调整:
startActivity(intent);startActivityForResult(intent, requestCode)(注意:AndroidX中推荐用registerForActivityResult,但老项目仍常用前者)。下面以“MainActivity跳转到ShowActivity”为例,分别讲解静态变量、putExtra、全局变量、Bundle这4种传参方式,每种方式都包含“传参代码”和“收参代码”,直接复制就能用。
静态变量传参是把参数存在目标Activity的静态字段中,A页面赋值后,B页面直接读取——优点是代码少,缺点是静态变量会常驻内存,容易引发内存泄漏,适合传递简单且临时的数据。
在目标页面(ShowActivity)中声明public静态变量,用于接收参数:
public class ShowActivity extends Activity {
// 定义静态变量,用于接收MainActivity传递的年龄
public static int age;
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
tvResult = findViewById(R.id.tv_result);
// 直接读取静态变量的值
tvResult.setText("静态变量传参:年龄=" + age);
}
}在源页面(MainActivity)中,给ShowActivity的静态变量赋值,再跳转:
public class MainActivity extends Activity {
private Button btnJump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnJump = findViewById(R.id.btn_jump);
btnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1. 给ShowActivity的静态变量赋值
ShowActivity.age = 25;
// 2. 构建Intent,指定跳转目标
Intent intent = new Intent(MainActivity.this, ShowActivity.class);
// 3. 跳转
startActivity(intent);
}
});
}
}putExtra是Intent自带的传参方法,支持字符串、整数、布尔值等基础数据类型,无需额外创建对象,直接通过“键值对”传递——这是日常开发中最常用的方式,简单且安全。
public class MainActivity extends Activity {
private Button btnJump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnJump = findViewById(R.id.btn_jump);
btnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ShowActivity.class);
// 传递字符串(键:"username",值:"Android开发者")
intent.putExtra("username", "Android开发者");
// 传递整数(键:"score",值:95)
intent.putExtra("score", 95);
// 传递布尔值(键:"isVip",值:true)
intent.putExtra("isVip", true);
startActivity(intent);
}
});
}
}在ShowActivity中,通过getIntent()获取Intent对象,再用对应类型的getXXXExtra方法读取参数(注意:键要和传参时一致,否则会拿到默认值):
public class ShowActivity extends Activity {
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
tvResult = findViewById(R.id.tv_result);
// 1. 获取传递过来的Intent对象
Intent intent = getIntent();
// 2. 读取参数(第二个参数是默认值,当键不存在时返回)
String username = intent.getStringExtra("username"); // 字符串
int score = intent.getIntExtra("score", 0); // 整数,默认0
boolean isVip = intent.getBooleanExtra("isVip", false); // 布尔值,默认false
// 显示结果
tvResult.setText("putExtra传参:\n用户名=" + username + "\n分数=" + score + "\n是否VIP=" + isVip);
}
}如果多个Activity都需要用到同一个数据(比如用户登录状态、Token),可以用全局变量——通过继承Application类,在整个App生命周期内共享数据,缺点是需要在Manifest中配置,略复杂。
新建Defind类(名字可自定义),继承Application,定义需要共享的变量和get/set方法:
public class Defind extends Application {
// 全局变量:存储用户QQ号(示例)
private String qq;
// get方法:供其他Activity获取变量值
public String getQq() {
return qq;
}
// set方法:供其他Activity设置变量值
public void setQq(String qq) {
this.qq = qq;
}
}打开AndroidManifest.xml,在<application>标签中添加android:name=".Defind",告诉系统使用我们自定义的Application类:
<application
android:name=".Defind" // 配置自定义Application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ShowActivity" /> // 注册ShowActivity
</application>public class MainActivity extends Activity {
private Button btnJump;
private Defind app; // 自定义Application对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnJump = findViewById(R.id.btn_jump);
// 1. 获取自定义Application对象
app = (Defind) getApplication();
btnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 2. 设置全局变量值
app.setQq("327388905");
// 3. 跳转
Intent intent = new Intent(MainActivity.this, ShowActivity.class);
startActivity(intent);
}
});
}
}public class ShowActivity extends Activity {
private TextView tvResult;
private Defind app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
tvResult = findViewById(R.id.tv_result);
// 1. 获取自定义Application对象
app = (Defind) getApplication();
// 2. 获取全局变量值
String qq = app.getQq();
tvResult.setText("全局变量传参:QQ号=" + qq);
}
}Bundle相当于“数据包”,可以把多个参数打包后传给Intent,适合传递多组数据,且支持序列化对象(需要实现Serializable或Parcelable)——比putExtra更灵活,推荐在传参较多时使用。
public class MainActivity extends Activity {
private Button btnJump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnJump = findViewById(R.id.btn_jump);
btnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ShowActivity.class);
// 1. 创建Bundle对象
Bundle bundle = new Bundle();
// 2. 往Bundle中添加参数(键值对)
bundle.putString("webUrl", "www.sunnyos.com"); // 网站地址
bundle.putInt("pageViews", 1000); // 页面浏览量
bundle.putDouble("rating", 4.8); // 评分(支持double类型)
// 3. 将Bundle添加到Intent中
intent.putExtras(bundle);
startActivity(intent);
}
});
}
}public class ShowActivity extends Activity {
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show);
tvResult = findViewById(R.id.tv_result);
// 1. 获取Intent中的Bundle
Intent intent = getIntent();
Bundle bundle = intent.getExtras(); // 也可以用intent.getBundleExtra("键"),如果传参时指定了键
// 2. 解析Bundle中的参数
String webUrl = bundle.getString("webUrl");
int pageViews = bundle.getInt("pageViews");
double rating = bundle.getDouble("rating");
// 显示结果
tvResult.setText("Bundle传参:\n网站地址=" + webUrl + "\n浏览量=" + pageViews + "\n评分=" + rating);
}
}intent.putExtra("userName", "张三")(键是userName),ShowActivity中却用intent.getStringExtra("username", "")(键是username)——大小写不一致会导致拿不到值,一定要确保键完全相同。ShowActivity.age=25,B页面又给ShowActivity.age=30,此时ShowActivity拿到的会是30,而非25。AndroidManifest.xml中添加android:name=".Defind",调用getApplication()时会拿到默认的Application对象,而非自定义的,导致全局变量为空。如果需要B页面处理后给A页面回传数据(比如A页面跳转到B页面选择图片,B页面把选中的图片路径回传给A),需要用startActivityForResult和setResult配合。
public class MainActivity extends Activity {
private Button btnSelect;
private TextView tvSelected;
private static final int REQUEST_CODE_SELECT = 100; // 请求码,用于识别返回结果
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSelect = findViewById(R.id.btn_select);
tvSelected = findViewById(R.id.tv_selected);
btnSelect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到B页面(选择页面),并期望返回结果
Intent intent = new Intent(MainActivity.this, SelectActivity.class);
startActivityForResult(intent, REQUEST_CODE_SELECT);
}
});
}
// 接收B页面返回的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 1. 先判断请求码(确保是我们发起的请求)
if (requestCode == REQUEST_CODE_SELECT) {
// 2. 判断结果码(确保B页面处理成功)
if (resultCode == RESULT_OK) {
// 3. 读取返回的数据
String selectedPath = data.getStringExtra("imagePath");
tvSelected.setText("选中的图片路径:" + selectedPath);
}
}
}
}public class SelectActivity extends Activity {
private Button btnConfirm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select);
btnConfirm = findViewById(R.id.btn_confirm);
btnConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1. 模拟选中图片,获取路径
String imagePath = "/sdcard/photo.jpg";
// 2. 构建返回的Intent
Intent data = new Intent();
data.putExtra("imagePath", imagePath);
// 3. 设置结果码和返回数据(RESULT_OK表示处理成功)
setResult(RESULT_OK, data);
// 4. 关闭当前页面,返回A页面
finish();
}
});
}
}传参方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
静态变量 | 代码简单,无需Intent携带 | 内存泄漏风险,值易被覆盖 | 简单临时数据,不推荐频繁使用 |
putExtra | 无需额外配置,支持基础数据类型 | 传参多的时候代码冗余 | 简单数据(1-3个参数),日常首选 |
全局变量 | 多页面共享,生命周期长 | 需要配置Application,占内存 | 全局数据(Token、用户状态) |
Bundle | 支持多参数、序列化对象 | 需要额外创建Bundle对象 | 多参数、复杂数据(如对象、列表) |
最后再提醒一句:无论用哪种方式,传参时都要注意“数据类型匹配”(比如putInt就要用getIntExtra收),且避免传递过大的数据(比如超过1MB的图片),否则可能导致Intent超限崩溃。掌握这4种方式,基本能应对Android开发中所有Activity传参场景~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。