Android?Activity!!!
安卓开发必懂Activity 从入门到实战彻底搞懂页面交互的核心一、先搞懂什么是 Activity官方定义很简洁Activity 是安卓系统中负责与用户交互的可视化组件它提供了一个可绘制的窗口用户通过这个窗口完成点击、输入、滑动等所有操作。简单来说每一个安卓页面本质上就是一个 Activity—— 比如微信的聊天页、朋友圈页、设置页分别对应着不同的 Activity 实例。但要注意Activity 并不是孤立存在的一个应用通常包含多个 Activity它们协同工作构成完整的用户体验比如从登录页跳转至首页就是两个 Activity 之间的切换Activity 由系统统一管理而非应用自身控制系统会根据内存情况、用户操作等动态创建、销毁 Activity这也是我们要重点关注生命周期的原因Activity 可以启动其他应用的 Activity比如调用系统相机、浏览器这也是安卓组件化、跨应用交互的核心逻辑之一。举个通俗的例子Activity 就像手机里的“窗口”我们打开微信相当于打开了一个“微信主窗口”主 Activity点击进入聊天就是打开了一个“聊天窗口”聊天 Activity退回主页面就是关闭“聊天窗口”回到“主窗口”。每个窗口有自己的状态也有自己的“生存规则”——这就是我们接下来要讲的生命周期。二、核心Activity 生命周期Activity 的生命周期就是它从“创建”到“销毁”的整个过程系统会在不同阶段调用对应的回调方法我们通过重写这些方法就能控制 Activity 在不同状态下的行为。这是安卓开发的高频考点也是避免页面崩溃、数据丢失的关键。Activity 有 6 个核心回调方法对应 4 种核心状态我们结合实际场景用最通俗的方式讲明白建议结合流程图记忆效果更佳1. 核心回调方法onCreate()生命周期的“初始化阶段”系统首次创建 Activity 时调用整个生命周期只执行一次。我们通常在这里做初始化操作加载布局setContentView、绑定控件、初始化 ViewModel、设置监听器等。比如打开微信聊天页onCreate() 会加载聊天界面的布局初始化消息列表。onStart()Activity 进入“可见但不可交互”状态时调用。此时 Activity 已经显示在屏幕上但还没有获得焦点比如被其他半透明窗口遮挡用户无法点击、输入。这个方法执行时间很短通常不需要做复杂操作。onResume()Activity 进入“可见且可交互”状态时调用也是我们最常用的方法之一。此时 Activity 处于前台用户可以正常操作点击按钮、输入文字我们可以在这里启动动画、恢复播放视频、刷新数据等。onPause()Activity 进入“暂停状态”时调用通常是因为有新的 Activity 覆盖在它上面比如弹出弹窗、切换到其他页面。此时 Activity 仍可见但不可交互我们需要在这里做“轻量清理”暂停动画、停止视频播放、保存临时数据比如输入框的内容避免消耗过多系统资源。onStop()Activity 进入“停止状态”时调用此时 Activity 完全被其他 Activity 覆盖不可见。系统可能会为了释放内存销毁这个 Activity因此我们需要在这里做“重量级清理”关闭网络连接、释放数据库资源、取消广播注册等。onDestroy()生命周期的“销毁阶段”系统销毁 Activity 前调用整个生命周期只执行一次。我们在这里做最终的资源释放销毁控件引用、取消异步任务、释放内存避免内存泄漏。2. 关键生命周期场景光记方法不够结合实际场景才能真正理解场景 1打开应用 → 进入主页面onCreate() → onStart() → onResume()场景 2从主页面切换到设置页主页面 onPause() → 设置页 onCreate() → onStart() → onResume() → 主页面 onStop()场景 3从设置页退回主页面设置页 onPause() → 主页面 onRestart() → onStart() → onResume() → 设置页 onStop() → onDestroy()场景 4按Home键退回桌面当前 Activity onPause() → onStop()再次打开应用onRestart() → onStart() → onResume()场景 5屏幕旋转比如从竖屏变横屏当前 Activity 会被销毁后重新创建执行流程onPause() → onStop() → onDestroy() → onCreate() → onStart() → onResume()这也是为什么旋转屏幕会丢失数据后面会讲解决方案。3. 生命周期避坑点新手最容易踩的 3 个坑一定要注意不要在 onPause()、onStop() 中做耗时操作比如网络请求否则会导致页面切换卡顿甚至 ANR应用无响应屏幕旋转时Activity 会重建若不做数据保存输入框内容、列表滚动位置等会丢失解决方案用 onSaveInstanceState(Bundle outState) 保存数据在 onCreate() 或 onRestoreInstanceState() 中恢复不要在 onDestroy() 中做过于复杂的操作因为系统可能会直接杀死 Activity 进程不执行 onDestroy()导致资源泄漏。三、实战必备Activity 启动模式5种按需选择当我们通过 startActivity() 启动一个 Activity 时系统会将其放入“返回栈”Task Stack中而启动模式决定了这个 Activity 如何创建、如何放入返回栈以及如何复用。合理选择启动模式能避免页面重复创建、返回逻辑混乱等问题提升应用体验。安卓提供 5 种启动模式其中 singleInstancePerTask 是 Android 12 新增我们按“适用场景核心逻辑”的方式逐个讲清楚1. standard核心逻辑每次启动 Activity都会新建一个实例不管这个实例是否已经存在新实例会放入当前返回栈的栈顶。适用场景大多数常规页面比如详情页、设置子页、搜索结果页。例如从商品列表连续点击不同商品每次都打开新的详情页返回时逐个退出符合用户预期。代码示例Manifest 中配置activity android:name.ui.DetailActivity android:launchModestandard/易错点误以为返回时会“合并同类项”实际上每次启动都是新实例返回时需要逐个退出。2. singleTop核心逻辑如果要启动的 Activity 已经在返回栈的栈顶则直接复用不新建实例系统会调用 onNewIntent() 方法刷新内容若不在栈顶则新建实例。适用场景通知点击进入的页面、顶部 Tab 容器、Home 页。例如点击通知进入消息中心若消息中心已在栈顶直接复用并刷新消息避免重复创建多个消息中心页面。代码示例代码中设置 FlagsstartActivity(new Intent(this, HomeActivity.class) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) .putExtra(tab, inbox));易错点仅栈顶复用时生效若目标 Activity 在栈内但不在栈顶仍会新建实例若想“清掉栈顶到目标 Activity 之间的页面并复用”需搭配 FLAG_ACTIVITY_CLEAR_TOP 使用。3. singleTask核心逻辑只要要启动的 Activity 在当前返回栈中存在就直接复用系统会将该 Activity 之上的所有页面全部清除让它成为栈顶并调用 onNewIntent()若不存在则新建实例作为栈根。适用场景应用主页面MainActivity、路由中转页、从外部唤起后需回到唯一主页的场景。例如打开应用后跳转多个页面再次点击主页图标清除所有中间页面回到主页面避免返回时多次点击才能退出。代码示例Manifest 中配置activity android:name.ui.MainActivity android:launchModesingleTask android:exportedtrue/易错点二次进入会清除该 Activity 之上的所有页面不适合需要保留多层历史回退的页面比如多步骤表单。4. singleInstance核心逻辑该 Activity 会独占一个返回栈整个系统中只有一个实例任何应用启动它都会复用这个实例且从它启动其他 Activity 时新 Activity 会放入另一个返回栈。适用场景极少用仅适合系统级页面比如来电界面、锁屏器、系统浮层。普通应用几乎不需要使用否则会导致用户体验割裂比如切换页面时返回栈跳转混乱。四、基础实战Activity 的基本使用步骤了解了核心概念和启动模式我们用一个简单的案例快速上手 Activity 的基本使用以 Java 为例Kotlin 类似1. 新建 Activity在 Android Studio 中右键包名 → New → Activity → Empty Views Activity填写 Activity 名称比如 MainActivity勾选“Generate Layout File”自动生成布局文件activity_main.xml。2. 配置 Manifest关键所有 Activity 必须在 AndroidManifest.xml 中声明否则系统无法识别。如果是主 Activity还需要配置 intent-filter指定为应用入口manifest ... lt;application ...gt; !-- 主 Activity 配置 -- activity android:name.MainActivity android:exportedtrue intent-filter action android:nameandroid.intent.action.MAIN/ category android:nameandroid.intent.category.LAUNCHER/ /intent-filter lt;/activitygt; !-- 其他 Activity 配置 -- activity android:name.SecondActivity android:exportedfalse/ /application /manifest注意exported 属性表示该 Activity 是否允许被其他应用启动主 Activity 需设为 true其他 Activity 若不对外提供设为 false 更安全。3. 编写布局文件在 activity_main.xml 中添加一个按钮用于跳转至 SecondActivityLinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:gravitycenter Button android:idid/btn_jump android:layout_widthwrap_content android:layout_heightwrap_content android:text跳转至第二个页面/ /LinearLayout4. 编写 Activity 逻辑在 MainActivity 中绑定按钮设置点击事件实现跳转功能在 SecondActivity 中实现返回功能// MainActivity.java public class MainActivity extends AppCompatActivity { Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 加载布局 setContentView(R.layout.activity_main); // 绑定按钮 Button btnJump findViewById(R.id.btn_jump); // 设置点击事件跳转至 SecondActivity btnJump.setOnClickListener(v - { Intent intent new Intent(MainActivity.this, SecondActivity.class); // 可选传递数据 intent.putExtra(name, Android 开发者); startActivity(intent); }); } } // SecondActivity.java public class SecondActivity extends AppCompatActivity { Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); // 接收 MainActivity 传递的数据 Intent intent getIntent(); String name intent.getStringExtra(name); Log.d(SecondActivity, 接收的数据 name); // 点击返回按钮关闭当前 Activity Button btnBack findViewById(R.id.btn_back); btnBack.setOnClickListener(v - finish()); // finish() 销毁当前 Activity } }五、高频避坑新手常犯的 Activity 错误结合日常开发经验整理了 4 个新手最容易踩的坑避开这些能少走很多弯路1. 忘记在 Manifest 中声明 Activity现象启动 Activity 时崩溃报错 “Activity not found”。解决所有 Activity 必须在 Manifest 中声明主 Activity 需配置 intent-filter非主 Activity 需指定 exported 属性。2. 屏幕旋转导致数据丢失现象旋转屏幕后输入框内容、列表滚动位置消失甚至页面崩溃。解决使用 onSaveInstanceState() 保存数据在 onCreate() 或 onRestoreInstanceState() 中恢复// 保存数据 Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(inputContent, editText.getText().toString()); // 保存输入框内容 } // 恢复数据两种方式二选一 Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState ! null) { String inputContent savedInstanceState.getString(inputContent); editText.setText(inputContent); } } // 或 Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); String inputContent savedInstanceState.getString(inputContent); editText.setText(inputContent); }3. 内存泄漏最常见危害最大现象应用卡顿、闪退通过 Profiler 查看发现内存占用持续升高。常见原因及解决Activity 中持有静态变量比如 static Context context this导致 Activity 销毁后无法被回收解决避免使用静态 Context若必须使用用 getApplicationContext()。异步任务AsyncTask、线程未取消持有 Activity 引用解决在 onDestroy() 中取消异步任务、终止线程。广播接收器、EventBus 未注销解决在 onStop() 或 onDestroy() 中注销。4. 启动模式选择错误现象页面重复创建、返回逻辑混乱比如点击返回不是回到上一个页面而是直接退出应用。解决根据页面场景选择启动模式记住核心原则常规页面用 standard主页用 singleTask通知入口页用 singleTop系统级页面用 singleInstance。六、总结吃透 Activity筑牢安卓开发基础Activity 作为安卓应用的“门面”是用户交互的核心也是安卓开发的基础中的基础。总结一下核心要点本质用户与应用交互的可视化窗口每个页面对应一个 Activity 实例核心生命周期6个回调方法掌握不同状态下的操作规范避免崩溃和数据丢失实战启动模式5种按需选择优化页面跳转逻辑避坑记住 Manifest 声明、数据保存、内存泄漏、启动模式这4个关键点