28、Android基础:Activity生命周期、Intent与Bundle、布局文件(XML)基础

说实话,Android开发入门,绕不开的就是Activity。它就像你App里的一个页面,一个窗口。你打开微信,看到聊天列表,那是一个Activity;点进某个人的对话框,那是另一个Activity。今天我们就来聊聊Activity的“生老病死”,以及怎么在页面之间传递消息、怎么把界面画出来。

一、Activity生命周期——它到底经历了什么?

Activity从创建到销毁,会经历一系列回调。我刚开始学的时候,总觉得这些回调很抽象,直到有一次调试一个闪退问题,才真正体会到生命周期的重要性。

核心回调有7个,按顺序来:

  1. onCreate():Activity第一次创建时调用。做初始化工作,比如加载布局、绑定事件。
  2. onStart():Activity变得可见,但还不能交互。
  3. onResume():Activity准备好和用户交互了。这是你App真正“活”起来的时刻。
  4. onPause():另一个Activity要覆盖上来,当前Activity暂停。保存一些轻量级数据,比如用户输入的内容。
  5. onStop():Activity完全不可见。释放资源,比如停止动画、解绑广播。
  6. onRestart():Activity从停止状态重新启动。很少单独用,但要知道有这回事。
  7. onDestroy():Activity被销毁。清理所有资源,防止内存泄漏。

重要提醒:onPause()里不要做耗时操作,比如网络请求、数据库写入。因为onPause执行完,下一个Activity才能显示。你想想看,用户点击了一个按钮,结果卡了半秒才跳转,体验多差。

我曾经在一个项目里,把大量数据保存逻辑写在了onPause里,结果导致页面切换卡顿。后来改到onStop里,问题就解决了。嗯,这里要注意,onStop也不适合做太重的操作,但比onPause宽松一些。

二、Intent与Bundle——页面之间的“信使”

Activity之间怎么通信?靠Intent。它就像一个信封,里面装着你要去的目的地(目标Activity),还可以附带一些数据(Bundle)。

2.1 显式Intent

直接指定要启动哪个Activity。最常用。

// 从MainActivity跳转到DetailActivity
val intent = Intent(this, DetailActivity::class.java)
startActivity(intent)

2.2 隐式Intent

不指定具体类,而是指定动作(Action)和数据(Data)。系统会找到能处理这个Intent的Activity。

// 打开浏览器
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.example.com"))
startActivity(intent)

我个人习惯,能用显式Intent就用显式,因为更安全、更可控。隐式Intent容易引发冲突,比如用户装了多个浏览器,系统会弹窗让用户选择。

2.3 Bundle——给Intent“塞点料”

Bundle就是一个键值对容器。你可以把字符串、整数、对象等放进去,然后通过Intent传递。

// 发送方
val intent = Intent(this, DetailActivity::class.java)
val bundle = Bundle().apply {
    putString("name", "张三")
    putInt("age", 25)
}
intent.putExtras(bundle)
startActivity(intent)

// 接收方(在DetailActivity中)
val name = intent.getStringExtra("name")
val age = intent.getIntExtra("age", 0)

小技巧:如果传递的数据比较复杂,比如一个用户对象,建议用Serializable或Parcelable。我个人更推荐Parcelable,性能更好。Kotlin里可以用@Parcelize注解,写起来很爽。

三、布局文件(XML)基础——把界面画出来

Android的界面,说白了就是用XML文件描述的。你写一个XML,系统把它解析成View树,然后渲染到屏幕上。

3.1 常用布局容器

布局名称 特点 适用场景
LinearLayout 线性排列,水平或垂直 简单的列表、表单
RelativeLayout 相对定位,子View之间可以相互参照 复杂布局,但嵌套层级容易变深
ConstraintLayout 约束布局,扁平化,性能好 几乎任何场景,强烈推荐
FrameLayout 帧布局,子View层叠 Fragment容器、覆盖层

我现在的项目,基本只用ConstraintLayout。为什么?因为它能减少布局嵌套,提升渲染性能。你想想看,一个页面如果嵌套了五六层LinearLayout,渲染起来得多慢。

3.2 一个简单的布局示例

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/titleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/clickBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击"
        app:layout_constraintTop_toBottomOf="@id/titleText"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

这段代码很简单:一个TextView显示文字,一个Button在它下面。注意看约束条件,我用layout_constraintTop_toTopOf="parent"把TextView固定在顶部居中,然后用layout_constraintTop_toBottomOf把Button放在TextView下方。

避坑指南:我曾经在ConstraintLayout里忘了给某个View加约束,结果运行时它直接跑到了屏幕左上角(0,0)位置。调试了半天才发现。记住:ConstraintLayout里的每个View,至少要有水平和垂直两个方向的约束,否则它不会乖乖待在你想要的位置。

四、知识体系总览

下面这张图,把今天讲的核心内容串起来了。你可以把它当作一个思维导图来理解。

Activity基础 生命周期 onCreate() → 初始化 onStart() → 可见 onResume() → 可交互 onPause() → 暂停 onStop() → 不可见 onDestroy() → 销毁 Intent与Bundle 显式Intent:指定目标类 隐式Intent:指定Action/Data Bundle:键值对传数据 Parcelable:传递复杂对象 布局文件(XML) LinearLayout:线性排列 RelativeLayout:相对定位 ConstraintLayout:约束布局 FrameLayout:帧布局 核心:Activity是页面容器,Intent是信使,XML是画布 三者配合,构成Android App的基本单元

五、实战要点总结

  • 生命周期要牢记:onCreate做初始化,onPause保存轻量数据,onDestroy释放资源。别搞反了。
  • Intent传数据:小数据用Bundle,大数据用Parcelable。别把Bitmap直接塞Intent里,会爆的。
  • 布局选型:能用ConstraintLayout就别用多层嵌套。扁平化布局,性能更好。
  • 调试技巧:如果布局显示不对,先检查约束条件是否完整。我经常用Layout Inspector看View树,很直观。

好了,今天的内容就到这里。Activity生命周期、Intent与Bundle、布局文件,这三块是Android开发的基石。你把这些搞懂了,后面学Fragment、Jetpack Compose都会轻松很多。


公众号:蓝海资料掘金营,微信deep3321