Android Studio中Activity自关闭及跨Activity回调执行代码问题
问题1:如何在Android Studio中从Activity自身关闭该Activity?
这个操作超简单!你只需要在当前Activity的代码里直接调用finish()方法就可以啦。这个方法会告诉系统销毁当前的Activity实例,把它从任务栈中移除,同时系统会自动回收该Activity占用的资源。
举个实际的例子,比如你给一个按钮设置点击事件,点击后关闭当前Activity:
Java 示例
// 假设你有一个关闭按钮 Button closeBtn = findViewById(R.id.btn_close); closeBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); // 关闭当前Activity } });
Kotlin 示例
btn_close.setOnClickListener { finish() // 直接调用即可 }
小补充:如果你的Activity是通过带结果返回的方式启动的,调用finish()前别忘了设置返回结果哦(这个在第二个问题里会详细说)。
问题2:从Activity A启动Activity B后,如何在B结束时执行A中的指定代码?
首先得指出你现有代码里的小问题:你在启动B之后调用了finish(),这会直接销毁Activity A,这样B结束后A已经不存在了,自然没法执行指定代码。所以第一步要去掉那个finish()调用,然后用带结果返回的启动方式,下面分两种主流方案给你讲解:
方案1:推荐使用Activity Result API(Jetpack 组件,适配新版Android)
这是Google现在推荐的方式,替代了旧的startActivityForResult方法。
步骤1:在Activity A中注册结果回调
在A的onCreate方法里初始化一个ActivityResultLauncher,用来处理B返回的结果:
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.Toast; public class ActivityA extends AppCompatActivity { private ActivityResultLauncher<Intent> startBForResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); // 注册结果回调 startBForResult = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { // 当B结束时,会触发这个回调 if (result.getResultCode() == Activity.RESULT_OK) { // 这里就是你要执行的A中的指定代码! Toast.makeText(this, "B已结束,执行A的自定义逻辑", Toast.LENGTH_SHORT).show(); // 如果B需要给A传数据,可以这样获取 Intent data = result.getData(); if (data != null) { String message = data.getStringExtra("from_b_message"); // 处理传递过来的数据 } } } ); } }
步骤2:在Activity A中启动Activity B
用刚才注册的Launcher来启动B,而不是原来的startActivity:
// 比如在A的某个按钮点击事件里启动B Button goToBBtn = findViewById(R.id.btn_go_to_b); goToBBtn.setOnClickListener(v -> { Intent intent = new Intent(ActivityA.this, ActivityB.class); startBForResult.launch(intent); // 用Launcher启动 // 注意:不要调用finish()!否则A会被销毁,接收不到结果 });
步骤3:在Activity B中设置返回结果并关闭
当B需要结束时,先设置返回结果(可选:携带数据),再调用finish():
// 比如在B的返回按钮点击事件里 Button backToABtn = findViewById(R.id.btn_back_to_a); backToABtn.setOnClickListener(v -> { // 可选:如果需要给A传数据,创建一个Intent Intent resultIntent = new Intent(); resultIntent.putExtra("from_b_message", "我是从B回来的"); // 设置结果码和数据 setResult(Activity.RESULT_OK, resultIntent); finish(); // 关闭B,触发A的回调 });
方案2:旧版startActivityForResult方法(已废弃,但仍可兼容旧版本)
如果你维护的是旧项目,还在使用API 29及以下的版本,可以用这个方法:
步骤1:在Activity A中启动B并传入请求码
Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivityForResult(intent, 100); // 100是自定义的请求码,用来区分不同的请求 // 同样不要调用finish()
步骤2:在Activity A中重写onActivityResult方法
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 匹配请求码和结果码 if (requestCode == 100 && resultCode == Activity.RESULT_OK) { // 这里执行A中的指定代码 Toast.makeText(this, "B已结束,执行A的自定义逻辑", Toast.LENGTH_SHORT).show(); // 获取B传递的数据 if (data != null) { String message = data.getStringExtra("from_b_message"); } } }
步骤3:Activity B中设置结果的代码和方案1完全一样
同样调用setResult(Activity.RESULT_OK, resultIntent)再finish()即可。
额外提示
如果你确实需要A在启动B时看起来被“关闭”(比如回到桌面),但又要保留A以便接收结果,可以用moveTaskToBack(true)代替finish(),这样A会被移到后台任务栈,不会被销毁,等B结束后依然能回到A并执行回调。
内容的提问来源于stack exchange,提问作者Chintan Mehta

