首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Android 开发踩坑记:Activity 间传参总是失败?4 种常用方式 + 完整代码示例,一次学会

Android 开发踩坑记:Activity 间传参总是失败?4 种常用方式 + 完整代码示例,一次学会

原创
作者头像
高老师
发布2025-09-18 16:04:37
发布2025-09-18 16:04:37
1990
举报

Android开发踩坑记:Activity间传参总是失败?4种常用方式+完整代码示例,一次学会

刚学Android开发时,最头疼的就是Activity间传参——明明在第一个页面放了参数,第二个页面却拿不到,要么报空指针,要么拿到的是默认值。后来才发现,Intent传参有很多“隐性规则”,比如静态变量要注意生命周期,Bundle传参要对应数据类型。今天就把Android中Activity间传参的4种常用方式拆解开,附完整代码和避坑点,新手也能跟着做。

一、先搞懂:为什么需要Intent传参?

在Android中,每个Activity都是独立的页面容器,比如“登录页”要把用户输入的账号传给“主页”,“商品列表页”要把选中的商品ID传给“商品详情页”——这些都需要通过Intent(意图)来实现。

Intent就像“信使”,负责在Activity之间传递“请求动作”和“附加数据”,它的核心作用是:

  1. 告诉系统“要跳转到哪个Activity”;
  2. 携带需要传递的参数(比如字符串、数字、对象等)。

另外,Activity间跳转分两种场景,传参方式也会对应调整:

  • 无返回值跳转:只需从A页面传参到B页面,用startActivity(intent)
  • 有返回值跳转:A页面跳转到B页面,B页面处理后要给A页面回传数据,用startActivityForResult(intent, requestCode)(注意:AndroidX中推荐用registerForActivityResult,但老项目仍常用前者)。

二、4种常用传参方式:附完整代码

下面以“MainActivity跳转到ShowActivity”为例,分别讲解静态变量、putExtra、全局变量、Bundle这4种传参方式,每种方式都包含“传参代码”和“收参代码”,直接复制就能用。

方式1:静态变量传参(最简单,但慎用)

静态变量传参是把参数存在目标Activity的静态字段中,A页面赋值后,B页面直接读取——优点是代码少,缺点是静态变量会常驻内存,容易引发内存泄漏,适合传递简单且临时的数据。

步骤1:ShowActivity中定义静态变量

在目标页面(ShowActivity)中声明public静态变量,用于接收参数:

代码语言:java
复制
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);
    }
}
步骤2:MainActivity中赋值并跳转

在源页面(MainActivity)中,给ShowActivity的静态变量赋值,再跳转:

代码语言:java
复制
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);
            }
        });
    }
}

方式2:putExtra传参(最常用,适合简单数据)

putExtra是Intent自带的传参方法,支持字符串、整数、布尔值等基础数据类型,无需额外创建对象,直接通过“键值对”传递——这是日常开发中最常用的方式,简单且安全。

步骤1:MainActivity中用putExtra传参
代码语言:java
复制
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);
            }
        });
    }
}
步骤2:ShowActivity中用getXXXExtra收参

在ShowActivity中,通过getIntent()获取Intent对象,再用对应类型的getXXXExtra方法读取参数(注意:键要和传参时一致,否则会拿到默认值):

代码语言:java
复制
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);
    }
}

方式3:全局变量传参(适合多页面共享数据)

如果多个Activity都需要用到同一个数据(比如用户登录状态、Token),可以用全局变量——通过继承Application类,在整个App生命周期内共享数据,缺点是需要在Manifest中配置,略复杂。

步骤1:创建自定义Application类

新建Defind类(名字可自定义),继承Application,定义需要共享的变量和get/set方法:

代码语言:java
复制
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;
    }
}
步骤2:在Manifest中配置Application

打开AndroidManifest.xml,在<application>标签中添加android:name=".Defind",告诉系统使用我们自定义的Application类:

代码语言:xml
复制
<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>
步骤3:MainActivity中设置全局变量
代码语言:java
复制
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);
            }
        });
    }
}
步骤4:ShowActivity中获取全局变量
代码语言:java
复制
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);
    }
}

方式4:Bundle传参(适合复杂数据,推荐)

Bundle相当于“数据包”,可以把多个参数打包后传给Intent,适合传递多组数据,且支持序列化对象(需要实现SerializableParcelable)——比putExtra更灵活,推荐在传参较多时使用。

步骤1:MainActivity中用Bundle打包参数
代码语言:java
复制
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);
            }
        });
    }
}
步骤2:ShowActivity中解析Bundle
代码语言:java
复制
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);
    }
}

三、避坑指南:这3个错误别再犯

  1. 传参和收参的“键”不一致undefined比如MainActivity中用intent.putExtra("userName", "张三")(键是userName),ShowActivity中却用intent.getStringExtra("username", "")(键是username)——大小写不一致会导致拿不到值,一定要确保键完全相同。
  2. 静态变量忘记赋值或被覆盖undefined静态变量是“全局共享”的,如果多个地方给同一个静态变量赋值,会导致值被覆盖。比如A页面给ShowActivity.age=25,B页面又给ShowActivity.age=30,此时ShowActivity拿到的会是30,而非25。
  3. 全局变量没在Manifest中配置undefined自定义Application类后,如果没在AndroidManifest.xml中添加android:name=".Defind",调用getApplication()时会拿到默认的Application对象,而非自定义的,导致全局变量为空。

四、扩展:有返回值的传参(A→B→A)

如果需要B页面处理后给A页面回传数据(比如A页面跳转到B页面选择图片,B页面把选中的图片路径回传给A),需要用startActivityForResultsetResult配合。

步骤1:A页面(MainActivity)发起带返回值的跳转
代码语言:java
复制
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);
            }
        }
    }
}
步骤2:B页面(SelectActivity)回传数据
代码语言:java
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android开发踩坑记:Activity间传参总是失败?4种常用方式+完整代码示例,一次学会
    • 一、先搞懂:为什么需要Intent传参?
    • 二、4种常用传参方式:附完整代码
      • 方式1:静态变量传参(最简单,但慎用)
      • 方式2:putExtra传参(最常用,适合简单数据)
      • 方式3:全局变量传参(适合多页面共享数据)
      • 方式4:Bundle传参(适合复杂数据,推荐)
    • 三、避坑指南:这3个错误别再犯
    • 四、扩展:有返回值的传参(A→B→A)
    • 五、总结:该选哪种传参方式?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档