Android语言基础教程(88)Android多个Activity的使用之调用另一个Activity并返回结果:Activity漂流记:一次“不归路”与“带娃回家”的编程奇遇

  • 时间:2025-11-16 20:16 作者: 来源: 阅读:0
  • 扫一扫,手机访问
摘要:嘿,各位在代码世界里摸爬滚打的准大神们!今天咱们来聊一个Android开发里既基础又贼重要的话题——多个Activity之间,怎么“呼来唤去”,还得让被叫走的那位“带点东西回来”。 想象一下这个场景:你(主Activity)在家里(主界面)舒舒服服躺着,突然想吃外卖了。这时候你有两个选择: 普通呼叫: 你打开外卖App(启动新Activity),看了一眼,然后直接按Home键溜了(按返回键)。

嘿,各位在代码世界里摸爬滚打的准大神们!今天咱们来聊一个Android开发里既基础又贼重要的话题——多个Activity之间,怎么“呼来唤去”,还得让被叫走的那位“带点东西回来”。

想象一下这个场景:你(主Activity)在家里(主界面)舒舒服服躺着,突然想吃外卖了。这时候你有两个选择:

普通呼叫: 你打开外卖App(启动新Activity),看了一眼,然后直接按Home键溜了(按返回键)。结果就是,你啥也没买,空手而归。这在代码里对应 startActivity(),一别两宽,各自安好。带任务呼叫: 你打开外卖App(启动新Activity),精挑细选,下单付款,然后App告诉你“订单已生成,预计30分钟送达”。最后你返回桌面,但你的手里(或者说,你的记忆里)多了一个“订单号”。这就是我们今天要说的 “调用另一个Activity并返回结果”

后一种情况,在编程世界里,我们称之为 “启动一个Activity以获得结果”。它就像是派你的小弟(新Activity)出去执行一个任务,任务完成后,他必须回来向你汇报,并且把任务成果(比如一份机密文件、用户的选择、一张拍好的照片)亲手交到你手上。

第一幕:出发前的准备——行李打包与接头暗号

在你派小弟出门之前,你得告诉他两件事:

你要去哪,干什么? (通过Intent指定目标Activity)我凭什么认定是你回来了? (请求码 Request Code)

在我们的外卖比喻里,“打开外卖App”这个动作,就是一个Intent。我们通过 startActivityForResult(intent, requestCode) 这个方法,来启动这次“带结果的旅程”。

requestCode 是个啥?
想象一下,你同时派了小弟A去买奶茶(请求码=1),又派了小弟B去取快递(请求码=2)。过了一会儿,小弟回来了,你光看脸可能记不清是谁,但如果你出门前给他们每人发了个不同颜色的帽子(请求码),你就能立刻分清:哦,戴红帽子(请求码=1)的是买奶茶的,我得问他奶茶买好了没。

这个 requestCode 就是你自定义的一个整数,用来在之后区分是哪个“小弟”回来了。

第二幕:小弟的独立任务——干活与打包结果

小弟(新Activity)被启动后,他会独立运行,拥有自己的界面和逻辑。比如,他可能是一个让用户选择联系人的界面,或者是一个拍照界面。

当他的任务完成时(用户选好了联系人,或者拍完了照片),他不能默默地自己关闭就完事了。他需要做两件事:

把任务结果打包。 (准备一个Intent,把数据放进去)设定任务状态。 (是成功完成了,还是用户取消了?)“自杀”并送回结果。 (调用 setResult() 然后 finish()

这里的关键方法是 setResult(int resultCode, Intent data)

resultCode 又是啥?
它用来告诉老大任务执行的大体情况,通常只有两个预定义的值:

Activity.RESULT_OK:任务圆满完成!这是你想要的。 Activity.RESULT_CANCELED:任务被取消了,用户啥也没干就按返回键溜了。

data 里面放啥?
这就是真正的“特产”了。它是一个Intent对象,你可以通过它的 putExtra() 方法,把任何你想带回去的数据塞进去,比如一个字符串、一个数字、一个对象等等。

小弟(新Activity)的代码模板长这样:



// 当小弟完成任务时(比如用户点击了“确认选择”按钮)
public void onConfirmButtonClick(View view) {
    Intent resultIntent = new Intent(); // 创建一个空Intent,专门用来装结果
    resultIntent.putExtra("KEY_SELECTED_DATA", "这是带回去的特产!"); // 打包特产
    setResult(Activity.RESULT_OK, resultIntent); // 告诉系统:我成功了,这是结果
    finish(); // 结束自己,踏上归途
}
 
// 如果用户啥也不干直接按返回键
@Override
public void onBackPressed() {
    setResult(Activity.RESULT_CANCELED); // 告诉系统:任务取消了,没结果
    finish(); // 结束自己
}
第三幕:家长的等待与接收——翘首以盼与处理“娃的作业”

老大(主Activity)在派小弟出门后,并不会傻等着。它会继续响应其他操作,该干嘛干嘛。但是,它心里一直记着这事儿,并且设立了一个 “专门的接待处”—— onActivityResult(int requestCode, int resultCode, Intent data) 方法。

一旦有任何一个小弟(被它启动的Activity)返回,系统就会自动调用这个“接待处”方法。老大需要在这里做三件事:

看帽子(requestCode): 确认是哪个小弟回来了?是买奶茶的还是取快递的?看脸色(resultCode): 任务成功了还是失败了?接包裹(data): 如果成功了,就拆开包裹(Intent data),拿出里面的特产(数据)。

老大(主Activity)的代码模板长这样:



// 启动小弟的代码
private static final int REQUEST_CODE_TAKE_OUT = 1001; // 定义一个独特的请求码
 
public void onStartTakeOutActivityClick(View view) {
    Intent intent = new Intent(this, TakeOutActivity.class); // 创建Intent,指定小弟是谁
    startActivityForResult(intent, REQUEST_CODE_TAKE_OUT); // 派小弟出门!
}
 
// 重写这个“接待处”方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data); // 这行代码最好一直留着
 
    // 第一步:看帽子,是派出去买外卖的小弟回来了吗?
    if (requestCode == REQUEST_CODE_TAKE_OUT) {
        
        // 第二步:看脸色,任务成功了吗?
        if (resultCode == Activity.RESULT_OK) {
            
            // 第三步:接包裹,拆特产!
            if (data != null) {
                String result = data.getStringExtra("KEY_SELECTED_DATA");
                // 拿到数据了,更新UI或者做其他逻辑
                TextView tvResult = findViewById(R.id.tv_result);
                tvResult.setText("外卖点好了!订单是:" + result);
            }
        } else if (resultCode == Activity.RESULT_CANCELED) {
            // 用户取消了,啥也没选
            Toast.makeText(this, "用户取消了选择", Toast.LENGTH_SHORT).show();
        }
    }
    // 未来还可以在这里用 else if 判断其他 requestCode,接待别的小弟
}
第四幕:完整示例——一个极简的“传话小纸条”App

理论说再多,不如代码跑一跑。下面是一个超级简单的完整示例。

功能: 主页面一个按钮,点击后打开第二个页面,在第二个页面输入一句话,点击确定后,这句话会显示在主页面。

1. activity_main.xml (主页面布局)



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
 
    <Button
        android:id="@+id/btn_go_to_second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="去第二个页面写句话" />
 
    <TextView
        android:id="@+id/tv_message_from_second"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="等待来自第二个页面的消息..."
        android:textSize="18sp" />
</LinearLayout>

2. MainActivity.java



public class MainActivity extends AppCompatActivity {
 
    private static final int REQUEST_CODE_SECOND_ACTIVITY = 1;
    private TextView tvMessage;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Button btnGo = findViewById(R.id.btn_go_to_second);
        tvMessage = findViewById(R.id.tv_message_from_second);
 
        btnGo.setOnClickListener(v -> {
            // 派小弟出门
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            startActivityForResult(intent, REQUEST_CODE_SECOND_ACTIVITY);
        });
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        // 确认是咱们等的小弟
        if (requestCode == REQUEST_CODE_SECOND_ACTIVITY) {
            // 看看任务状态
            if (resultCode == Activity.RESULT_OK) {
                // 拆包裹,拿数据
                if (data != null) {
                    String message = data.getStringExtra("EXTRA_MESSAGE");
                    tvMessage.setText("第二个页面说: " + message);
                }
            } else {
                tvMessage.setText("对方啥也没说就回来了...");
            }
        }
    }
}

3. activity_second.xml (第二个页面布局)



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
 
    <EditText
        android:id="@+id/et_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="在这里输入你想带回主页的话" />
 
    <Button
        android:id="@+id/btn_confirm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="确认并返回" />
</LinearLayout>

4. SecondActivity.java



public class SecondActivity extends AppCompatActivity {
 
    private EditText etInput;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
 
        etInput = findViewById(R.id.et_input);
        Button btnConfirm = findViewById(R.id.btn_confirm);
 
        btnConfirm.setOnClickListener(v -> sendMessageBack());
    }
 
    private void sendMessageBack() {
        String message = etInput.getText().toString().trim();
        Intent resultIntent = new Intent();
        
        // 即使为空,也把空字符串带回去
        resultIntent.putExtra("EXTRA_MESSAGE", message); 
        
        // 设置结果为成功,并附上数据
        setResult(Activity.RESULT_OK, resultIntent);
        finish(); // 结束自己,返回主页面
    }
 
    // 处理返回键,视为取消
    @Override
    public void onBackPressed() {
        setResult(Activity.RESULT_CANCELED);
        finish();
    }
}
尾声:避坑指南与未来展望

恭喜你!看到这里,你已经掌握了Activity之间“带娃回家”的核心奥义。最后再唠叨几个容易掉进去的坑:

请求码别重复: 如果你要启动多个不同的Activity拿结果,记得给它们分配独一无二的 requestCode判空是美德: onActivityResult 里处理 data 之前,最好先判断一下它是不是 null,防止空指针异常。 finish() 是关键: 小弟一定要记得调用 setResult() 之后 finish(),不然他会一直赖在屏幕上,结果也送不回去。

虽然现在更现代的 Activity Result API Jetpack Compose 有了新的方式,但 startActivityForResult/onActivityResult 这套机制是理解整个流程的基石,掌握了它,万变不离其宗。

希望这次“Activity漂流记”能让你在Android开发的路上,少掉几根头发,多几分从容!快去你的代码里试试吧,让Activity们愉快地“交流”起来!

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】UEFI+GPT平台一键安装Windows方法(2025-11-16 20:16)
【系统环境|】Android语言基础教程(88)Android多个Activity的使用之调用另一个Activity并返回结果:Activity漂流记:一次“不归路”与“带娃回家”的编程奇遇(2025-11-16 20:16)
【系统环境|】【2025】下载安装Anaconda(Python语言)(2025-11-16 20:15)
【系统环境|】Docker Desktop使用教程(2025-11-16 20:15)
【系统环境|】go语言安装及环境配置(史上最详细)(2025-11-16 20:14)
【系统环境|】树莓派UBUNTU 24.04 PART6 安装好后运行的第一个程序(2025-11-16 20:14)
【系统环境|】Java与AI的深度交融:深度学习模型部署的Java实践指南(2025-11-16 20:13)
【系统环境|】Android Studio安装(2025-11-16 20:13)
【系统环境|】MySQL + Docker:初始设置(2025-11-16 20:12)
【系统环境|】Proxmox VE安装OpenWRT(2025-11-16 20:12)
手机二维码手机访问领取大礼包
返回顶部