深入分析 Android Activity (三)
深入分析 Android Activity (三)
1. Activity 的配置变化处理
当设备配置(如屏幕方向、语言、屏幕大小等)发生变化时,默认情况下,Android 会销毁并重新创建当前的 Activity。这种行为确保了新配置能够正确应用,但在某些情况下,重新创建 Activity 会带来性能问题或不必要的复杂性。
可以通过 android:configChanges 属性来指定当特定配置变化发生时,不销毁 Activity,而是调用 onConfigurationChanged 方法。
1.1 处理配置变化
在 AndroidManifest.xml 文件中声明需要处理的配置变化:
<activity android:name=".MyActivity"android:configChanges="orientation|screenSize|keyboardHidden">
</activity>
在 Activity 中覆盖 onConfigurationChanged 方法以处理配置变化:
@Override
public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);// Handle configuration changesif (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {// Handle landscape orientation} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {// Handle portrait orientation}
}
2. Activity 的存储和恢复状态
为了在配置变化、进程被终止或其他情况发生时保存和恢复 Activity 的状态,可以使用 onSaveInstanceState 和 onRestoreInstanceState 方法。
2.1 保存状态
onSaveInstanceState 方法在 Activity 即将被销毁时调用,用于保存临时状态信息:
@Override
protected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString("key", "value");
}
2.2 恢复状态
onRestoreInstanceState 方法在 Activity 被重新创建后调用,用于恢复之前保存的状态信息:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);String value = savedInstanceState.getString("key");
}
也可以在 onCreate 方法中恢复状态:
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (savedInstanceState != null) {String value = savedInstanceState.getString("key");}
}
3. Activity 与 Fragment 的通信
Fragment 是一个可重用的 UI 组件,能够在 Activity 中管理部分 UI 和逻辑。Fragment 可以独立于 Activity 管理自己的生命周期和状态。
3.1 通过接口进行通信
Activity 和 Fragment 之间可以通过接口进行通信。在 Fragment 中定义一个接口,并在 Activity 中实现它:
public class MyFragment extends Fragment {private OnFragmentInteractionListener mListener;public interface OnFragmentInteractionListener {void onFragmentInteraction(String data);}@Overridepublic void onAttach(Context context) {super.onAttach(context);if (context instanceof OnFragmentInteractionListener) {mListener = (OnFragmentInteractionListener) context;} else {throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");}}// Call this method to send data to the activitypublic void sendDataToActivity(String data) {if (mListener != null) {mListener.onFragmentInteraction(data);}}
}
在 Activity 中实现接口方法:
public class MyActivity extends AppCompatActivity implements MyFragment.OnFragmentInteractionListener {@Overridepublic void onFragmentInteraction(String data) {// Handle interaction with the fragment}
}
3.2 通过 ViewModel 进行通信
使用 ViewModel 和 LiveData 可以在 Activity 和 Fragment 之间进行数据共享和通信,尤其是在 MVVM 架构中:
public class SharedViewModel extends ViewModel {private final MutableLiveData<String> selected = new MutableLiveData<String>();public void select(String item) {selected.setValue(item);}public LiveData<String> getSelected() {return selected;}
}
在 Activity 中:
public class MyActivity extends AppCompatActivity {private SharedViewModel viewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);viewModel = new ViewModelProvider(this).get(SharedViewModel.class);viewModel.getSelected().observe(this, new Observer<String>() {@Overridepublic void onChanged(@Nullable String item) {// Update the UI}});}
}
在 Fragment 中:
public class MyFragment extends Fragment {private SharedViewModel viewModel;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_my, container, false);viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);viewModel.getSelected().observe(getViewLifecycleOwner(), new Observer<String>() {@Overridepublic void onChanged(@Nullable String item) {// Update the UI}});return view;}
}
4. Activity 的窗口管理和视图层次结构
4.1 DecorView
DecorView 是 Activity 窗口中的最顶层视图容器,包含了状态栏、标题栏和内容区域。Window 类通过 setContentView 将视图层次结构添加到 DecorView 中。
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
}
4.2 Window 和 WindowManager
Window 是一个抽象类,表示一个顶级窗口。在大多数情况下,Activity 使用 PhoneWindow 类,它是 Window 的具体实现。WindowManager 是一个系统服务,负责管理窗口。
通过 Window 和 WindowManager 可以控制窗口的布局参数:
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(params);
5. Activity 的任务和返回栈(Back Stack)
Android 使用任务和返回栈来管理 Activity 的导航。每个任务由一个栈(返回栈)来管理 Activity。
5.1 启动 Activity 的 Intent 标志
可以使用 Intent 标志来控制 Activity 的启动行为和返回栈。例如:
FLAG_ACTIVITY_NEW_TASK:在新的任务中启动Activity。FLAG_ACTIVITY_CLEAR_TOP:如果目标Activity已经在栈中存在,则将其上面的所有Activity清除。
Intent intent = new Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
5.2 处理返回栈中的数据
可以使用 onActivityResult 方法处理从另一个 Activity 返回的数据:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {String result = data.getStringExtra("key");// Handle the result}
}
在启动 Activity 时可以传递请求代码:
Intent intent = new Intent(this, AnotherActivity.class);
startActivityForResult(intent, REQUEST_CODE);
总结
Android 的 Activity 设计涉及生命周期管理、启动模式、视图层次结构、与 Fragment 的交互、进程和线程模型、任务和返回栈管理、以及配置变化处理。理解这些关键概念和内部实现,有助于开发者创建高效、稳定和响应迅速的应用程序。通过灵活应用这些知识,可以提升应用程序的用户体验和性能。
相关文章:
深入分析 Android Activity (三)
深入分析 Android Activity (三) 1. Activity 的配置变化处理 当设备配置(如屏幕方向、语言、屏幕大小等)发生变化时,默认情况下,Android 会销毁并重新创建当前的 Activity。这种行为确保了新配置能够正确应用,但在某…...
电影《朝云暮雨》观后感
上周看了电影《朝云暮雨》,看完之后,感觉自己整个人都不太好了,也不是说电影太差,只是觉得电影没有传达正能量,让人很不舒服。 (1)演技在线 对于著名的演员“范伟”,或者说&#x…...
Isaac Sim仿真平台学习(1)认识Isaac Sim
0.前言 上一个教程中我们下载好了Isaac Sim,这一章我们将来简单了解一下Isaac Sim平台。 isaac Sim仿真平台安装-CSDN博客 1.Isaac Sim是啥? What Is Isaac Sim? — Omniverse IsaacSim latest documentation Isaac Sim是NVDIA Omniverse平台的机器…...
C++:vector基础讲解
hello,各位小伙伴,本篇文章跟大家一起学习《C:vector基础讲解》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 ! 如果本篇文章对你有帮助,还请各位点点赞!&#…...
Grafana 路径遍历所有路径 CVE-2021-43798漏洞预警
简介 Grafana是一个跨平台、开源的数据可视化网络应用程序平台。用户配置连接的数据源之后,Grafana可以在网络浏览器里显示数据图表和警告。 漏洞危害等级 高危 CVE 编号 CVE-2021-43798 FOFA查询 app"Grafana" zoomeyes查询 app:"gr…...
基于Docker部署GitLab环境搭建
文件在D:\E\学习文档子目录压缩\专项进阶,如ngnix,webservice,linux,redis等\docker 建议虚拟机内存2G以上 1.下载镜像文件 docker pull beginor/gitlab-ce:11.0.1-ce.0 注意:一定要配置阿里云的加速镜像 创建GitLab 的配置 (etc) 、 日志 (log) 、数…...
初始化是什么
定义 初始化(Initialization)是指在计算机科学和软件开发中,将系统、变量、对象或其他可用组件设置为其初始状态或初始值的过程。这通常是在程序开始执行或组件第一次使用之前进行的,以确保其处于可预测和稳定的状态。 初始化的…...
Python图形界面(GUI)Tkinter笔记(九):用【Button()】功能按钮实现人机交互
在Tkinter库中,功能按钮(Button)是实现人机交互的一个非常重要的组件: 【一】主要可实现功能及意义: (1)响应用户交互: Button组件允许用户通过点击来触发某个事件或动作。当用户点击按钮时,可以执行一个指定的函数或方法。 (2)提供用户输入: Button组件是图形用户界面(G…...
linux 内核安装、切换版本,禁用内核更新
安装内核 版本5.15.0-105 sudo apt-get install linux-image-5.15.0-105-generic sudo apt-get install linux-headers-5.15.0-105-generic切换内核版本 #查看已安装内核版本 grep menuentry /boot/grub/grub.cfg sudo dpkg --get-selections |grep linux-image#修改文件/etc…...
充电桩中PE接地实时监测的一种电路.pdf
pdf下载链接:https://pan.baidu.com/s/18k8tEwa6h3WAOGJs3lAsTQ 提取码:Ronv...
鲲泰新闻丨第七届数字中国建设峰会正式启幕,神州鲲泰携手天翼云共筑智算云生态
2024年5月23日,由国家发展改革委、国家数据局、国家网信办、科技部、国务院国资委、福建省人民政府共同主办的“第七届数字中国建设峰会”在福建省福州市海峡国际会展中心盛大开幕。 数字中国建设峰会是展示数字中国建设成就的盛会,本次峰会以“释放数据…...
零基础学Java第二十二天之IO流之内存流,打印流,随机流
IO流之内存流,打印流,随机流 1、内存流 1、理解 内存流"(Memory Stream)在计算机编程中通常指的是一种特殊的数据流,它在内存中存储和操作数据,而不是在外部存储(如硬盘、网络等…...
vue-router路由懒加载以及三种实现方式
什么是路由懒加载? 延迟加载或按需加载路由所对应的组件,而不是在应用初始化时就一次性加载所有组件。 路由懒加载做了什么事情? 主要作用是将路由对应的组件打包成一个个的js代码块 只有在这个路由被访问到的时候,才加载对应…...
Java轻松转换Markdown文件到Word和PDF文档
Markdown 凭借其简洁易用的特性,成为创建和编辑纯文本文档的常用选择。但某些时候我们需要更加精致的展示效果,例如在专业分享文档或打印成离线使用的纸质版时,就需要将Markdown文件以其他固定的文档格式呈现。通过将 Markdown 转换为 Word 和…...
【JAVA基础之内部类】匿名内部类
🔥作者主页:小林同学的学习笔录 🔥小林同学的专栏:JAVA之基础专栏 目录 1.内部类 1.1 概述 1.1.1 什么是内部类 1.1.2 什么时候使用内部类 1.2 内部类的分类 1.3 成员内部类 1.3.1 获取成员内部类对象的两种方式 1.3.2 经典面试…...
远动通讯屏的原理和应用
远动通讯屏的原理和应用 远动通讯屏,是一种集显示和远程控制于一体的智能化控制设备。它可以通过网络、通信线路等方式实现与远程设备的通讯和交互,从而实现远程监控和控制。 远动通讯屏实现远程控制的核心原理是基于PLC(Programmable Logic …...
C++ (week4):Linux基础
文章目录 零、Linux简介1.配置环境2.Linux历史3.Linux模型 一、vim二、Linux命令行 (shell命令)1.常用命令与快捷键(1)常用命令①man命令:查看帮助手册 (2)快捷键 2.用户子系统(1)Linux用户(2)用户命令 3.文件子系统命令(1)目录命令1.创建文件:mkdir2.删…...
如何将手机中的音乐转移到 SD 卡上?轻松传输音乐
概括 如何将音乐从手机转移到 SD 卡?我们的智能手机可以充当个人点唱机,因此有效管理我们的音乐库变得至关重要。无论您是存储空间不足还是只是想整理您的音乐收藏,将音乐从手机传输到 SD 卡都是一个实用的解决方案。 在本指南中࿰…...
JKTECH柔性振动盘用途
柔性振动盘的作用与用途 在现代工业自动化领域,柔性振动盘凭借其独特的功能和广泛的应用场景,正逐渐成为生产线上的重要工具。柔性振动盘,又称柔性供料器,它结合了传统振动盘的高效性和现代自动化技术的灵活性,为各种…...
【职场心灵伴侣】文心一言智能体
【文心一言】智能体 写在最前面名称和简介:职场心灵伴侣AI生成头像添加工具智能体调优 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~ 🚀 欢迎一起踏上探险之旅,挖掘无限…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
