嘿,各位未来的安卓大神们,今天咱们不聊风花雪月,来聊点App里的“人情世故”。想象一下,你的App就像一个热闹的派对,而每一个页面(Activity)就是派对里一个个独立的房间。用户点击图标,进入大厅(主Activity),然后他想去书房(另一个Activity)看看,或者去游戏室(又一个Activity)玩两把。
那么问题来了:怎么从一个房间优雅地走到另一个房间?玩够了,又该怎么潇洒地关门离开,甚至还能带点“纪念品”回来?
这就是今天我们要深入唠嗑的主题:Activity的启动与关闭。别皱眉,这事儿可比你想象中有趣多了,简直就是一场代码界的“相亲与分手大戏”!
一个Activity,从它在
AndroidManifest.xml里注册户口的那一刻起,就注定要走上舞台。但它的亮相方式,有两种截然不同的“剧本”。
剧本一:“直球式相亲”——显式启动
这就像你妈直接把你拉到隔壁老王家闺女面前:“喏,就是她,你俩认识一下。” 目标明确,毫不含糊。
在代码里,就是这么直接:
// 假设你在 MainActivity,现在想跳转到 ProfileActivity
Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
startActivity(intent);
Intent(意图):它就是你的“媒人”,负责传递你的意愿。这里,媒人手里拿着明确的“地址”——
ProfileActivity.class。
startActivity(intent):媒人用力一推,“嘭”一声,你就从
MainActivity的现场,瞬移到了
ProfileActivity的闺房。
特点:简单、粗暴、高效。在自己家的App内部跳转,基本都用它。缺点:不够灵活,只能找自己认识的(同一个App内的Activity)。
剧本二:“海王式征友”——隐式启动
这就像你在朋友圈发了个状态:“今晚想找个能聊量子力学和吃火锅的地方,求推荐!” 你并不指定具体哪个人,而是抛出一个条件,谁符合条件,谁就可以来响应你。
在代码里,就是这么“海王”:
// 我想打开一个网页,但我不知道用户手机里装的是Chrome、QQ浏览器还是火狐
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
startActivity(intent);
这时,系统会弹出一个选择框,列出所有声明自己能处理
ACTION_VIEW这个动作,并且能处理
https协议数据的App(也就是各种浏览器),让你自己选。
搭建“隐式相亲”舞台的关键两步:
在
AndroidManifest.xml里为你的Activity发“征友广告”:
MyWebViewActivity也能响应这种打开网页的请求。
<activity android:name=".MyWebViewActivity">
<intent-filter>
<!-- 动作:我要查看 -->
<action android:name="android.intent.action.VIEW" />
<!-- 数据类型:http/https -->
<category android:name="android.intent.category.DEFAULT" />
<!-- 协议:必须是网页链接 -->
<data android:scheme="https" />
<data android:scheme="http" />
</intent-filter>
</activity>
这样,当别人发起隐式Intent打开网页时,你的
MyWebViewActivity就会出现在候选名单里!
特点:强大、灵活,可以实现App之间的协同工作。比如“分享”功能,本质上就是一个隐式Intent。缺点:不确定性高,如果没找到合适的Activity,App会崩溃,所以使用时最好用
resolveActivity检查一下。
一个Activity完成了它的使命,就该退场了。关门,通常有两种姿势。
姿势一:“默默自我了断”
最简单的方式,就是在Activity内部调用
finish()方法。就像你觉得自己该回家了,跟谁也没说,自己悄悄溜走。
// 在 ProfileActivity 中,比如点击了“返回”按钮
public void onBackButtonClicked(View view) {
finish(); // 优雅地关上当前的门,回到上一个Activity
}
姿势二:“让对方下逐客令”
有时候,你启动了一个Activity,是希望它干完活后给你一个结果的。比如,你从“联系人列表”启动“选择联系人”页面,你希望它返回时告诉你用户选了谁。
这时候,关门就不能只用
finish()了,还得把“信物”带回去。
这就引出了我们高潮部分:带结果的启动!
这个场景太常见了:发朋友圈要选照片、下单要选地址……都是你(Activity A)派一个小弟(Activity B)去办事,办完了还得回来向你汇报。
Step 1: 带着期待去启动 (Start for Result)
在
MainActivity里,我们不是用普通的
startActivity,而是用
startActivityForResult(或者在新的Activity Result API中,用
registerForActivityResult)。
这里我们用更现代、更推荐的
registerForActivityResult来演示:
// 在 MainActivity 中
// 1. 定义一个“契约”,告诉系统你想启动什么类型的Activity,以及期望返回什么数据
private ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> { // 2. 这是一个回调,当B页面关闭回来时,系统会自动调用这里
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
if (data != null) {
String selectedData = data.getStringExtra("SELECTED_DATA");
// 拿到数据了!更新UI或者做其他操作
textView.setText("你选择的是: " + selectedData);
}
} else {
// 对方可能取消了操作
textView.setText("你取消了选择。");
}
});
// 3. 点击按钮,启动“选择页面”
public void onSelectButtonClicked(View view) {
Intent intent = new Intent(this, SelectionActivity.class);
launcher.launch(intent); // 使用launcher来启动,而不是startActivity
}
Step 2: 办事并带回结果 (Set Result and Finish)
在
SelectionActivity里,当用户做出选择后(比如点击了一个选项),我们需要把结果塞回去,然后再关门。
// 在 SelectionActivity 中
public void onItemSelected(String selectedItem) {
Intent resultIntent = new Intent();
resultIntent.putExtra("SELECTED_DATA", selectedItem); // 把数据放进“信封”
setResult(RESULT_OK, resultIntent); // 告诉系统:“我成功办完事了,这是结果”
finish(); // 然后才关门回家
}
// 如果用户啥也没选,直接按返回键
@Override
public void onBackPressed() {
setResult(RESULT_CANCELED); // 告诉系统:“任务取消了”
finish();
}
看明白这出戏了吗?
MainActivity像个老父亲,派
SelectionActivity儿子去提亲,并嘱咐:“成不成,给个信儿!” (
registerForActivityResult)。
SelectionActivity到了地方,如果提亲成功,就打包好彩礼 (
putExtra),发个成功信号 (
RESULT_OK) 然后回家 (
finish)。老父亲一直竖着耳朵听着呢,一听到儿子回来的动静(回调被触发),赶紧看信号:成功了就开箱验货 (
getStringExtra),失败了就叹口气。
整个过程,逻辑清晰,耦合度低,堪称Activity间的“优雅协作范本”。
为了让你亲手把玩,这里有一个超简单的完整代码。
1.
activity_main.xml (主界面布局)
就是一个按钮和一个文本框。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ...>
<Button
android:id="@+id/btn_launch"
android:text="去选择你的最爱"
... />
<TextView
android:id="@+id/tv_result"
android:text="等待你的选择..."
... />
</LinearLayout>
2.
MainActivity.java (主Activity)
public class MainActivity extends AppCompatActivity {
private TextView tvResult;
private ActivityResultLauncher<Intent> launcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
Button btnLaunch = findViewById(R.id.btn_launch);
// 初始化Activity结果启动器
launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
// 当SelectionActivity返回时,这里被调用
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
if (data != null) {
String favorite = data.getStringExtra("FAVORITE_THING");
tvResult.setText("你的最爱是: " + favorite + " ❤️");
}
} else {
tvResult.setText("哎呀,你还没做出选择呢~");
}
});
btnLaunch.setOnClickListener(v -> {
// 启动SelectionActivity
Intent intent = new Intent(MainActivity.this, SelectionActivity.class);
launcher.launch(intent);
});
}
}
3.
activity_selection.xml (选择界面布局)
就几个按钮。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ...>
<Button android:id="@+id/btn_food" android:text="美食" ... />
<Button android:id="@+id/btn_travel" android:text="旅行" ... />
<Button android:id="@+id/btn_sleep" android:text="睡觉" ... />
</LinearLayout>
4.
SelectionActivity.java (选择Activity)
public class SelectionActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_selection);
findViewById(R.id.btn_food).setOnClickListener(v -> returnResult("美食"));
findViewById(R.id.btn_travel).setOnClickListener(v -> returnResult("旅行"));
findViewById(R.id.btn_sleep).setOnClickListener(v -> returnResult("睡觉"));
}
private void returnResult(String selectedThing) {
Intent resultIntent = new Intent();
resultIntent.putExtra("FAVORITE_THING", selectedThing);
setResult(RESULT_OK, resultIntent); // 设置结果码和数据
finish(); // 关闭自己
}
@Override
public void onBackPressed() {
setResult(RESULT_CANCELED); // 如果按返回键,表示取消
finish();
}
}
跑起来这个App,点击按钮,做出选择,然后观察主页面文本框的变化。你会亲眼见证数据是如何在不同“房间”之间传递的,这种感觉,爽过喝肥宅快乐水!
好了,各位“Activity情感大师”,今天的课程就到这里。我们经历了直球相亲与海王征友,也学会了体面分手和如何带着“战利品”光荣归来。
记住,Activity的生命周期和启动模式是安卓开发的基石。理解并熟练运用它们,你就能设计出流程清晰、用户体验流畅的App。别再让你家的Activity在后台默默“摸鱼”或者“迷路”了,给它们安排好每一次的“出场”和“退场”,你的App才能真正地“活”起来。
现在,打开Android Studio,亲手导演一出属于你自己的“页面情缘”吧!
¥56.00
预售 【中商原版】当我谈跑步时我在谈些什么 关于跑步我说的其实是 日文原版 走ることについて語るときに僕の語ること 村上春树
¥19.80
XGPU2个月充值卡Xbox Game Pass Ultimate一年123年终极会员pc主机EA Play金会员14天xgp兑换码激活码礼品卡
¥32.99
XGPU 4个月充值卡 Xbox Game Pass Ultimate终极会员 pc主机 EA Play金会员 xgp兑换码激活礼品卡pgp
¥34.99
XGPU 4个月充值卡 Xbox Game Pass Ultimate 终极会员 pc主机 EA Play金会员 xgp兑换码激活码礼品卡pgp
¥13.85
鹅鸭杀兑换码金币充值恶魔女猎手港湾鹅鸭杀扭蛋机代币激活码cdkey皮肤礼包goose goose duck狼人杀鹅鸭游戏
¥19.70
XGPU2个月充值卡Xbox Game Pass Ultimate一年123年终极会员xgp14天pc EA Play金会员pgp兑换码激活码礼品卡