Android开发 Activity启动模式、ViewModel与LiveData,及Kotlin Coroutines
目录
Activity启动模式
onNewIntent解释
Activity启动模式的考虑时机
Service启动模式
ContentProvider的作用
Broadcast的注册方式
AsyncTask的作用
ViewModel
LiveData
Kotlin Coroutines
结合使用
Activity启动模式
Android中Activity的启动模式有四种,分别是:
- standard(标准):每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。
- singleTop(栈顶复用):如果新的Activity已经位于任务栈的栈顶,那么这个Activity不会被重新创建,同时它的
onNewIntent方法会被调用。如果Activity不在栈顶,还是会重新创建一个新的实例。 - singleTask(栈内复用):系统先检查是否存在Activity的实例,如果存在就调用其
onNewIntent方法,并把在它之上的所有其他Activity实例统统出栈,如果不存在,则新建实例。 - singleInstance(单实例模式):在一个单独的任务栈中创建该Activity的实例,这个模式下的Activity只能单独地位于一个任务栈中。
onNewIntent解释
在Android开发中,onNewIntent(Intent)是Activity的一个回调方法。当当前Activity启用了singleTop、singleTask或singleInstance启动模式,并且该Activity已经存在于任务栈中时,再次启动该Activity不会创建一个新的实例,而是会调用现有实例的onNewIntent(Intent)方法,并传入新的Intent。这个方法允许Activity更新其内容而不需要重新创建。
Activity启动模式的考虑时机
Activity启动模式的选择主要考虑以下几个方面:
- 任务和返回栈管理:根据应用的结构和用户的导航需求,选择合适的启动模式以合理管理任务(App中的一系列Activity集合)和返回栈(用户返回路径)。
- 避免重复实例:为了避免不必要的Activity实例堆积,可以选择合适的模式来复用Activity实例。
- Intent处理:如果Activity需要处理新的Intent(如搜索请求),可能需要通过
onNewIntent方法来更新Activity的显示内容而不是创建新的实例。
代码上,首先需要在AndroidManifest.xml中定义Activity的启动模式。比如设置MainActivity的启动模式为singleTop
<activity android:name=".MainActivity"android:launchMode="singleTop">
</activity>
然后,在MainActivity中重写onNewIntent方法:
class MainActivity : AppCompatActivity() {override fun onNewIntent(intent: Intent?) {super.onNewIntent(intent)}
}
Service启动模式
Service有两种启动方式:
- startService:通过调用
startService(Intent)来启动。Service将在后台无限期运行,即使启动它的组件已被销毁也如此。需要通过stopSelf()或stopService(Intent)来停止Service。 - bindService:通过调用
bindService(Intent, ServiceConnection, int)来实现。Service与调用组件绑定,调用组件如果被销毁了,Service也会被销毁。
IntentService:是Service的子类,用于处理异步请求(执行在工作线程)。客户端通过startService(Intent)方法发送请求,该服务在每次处理完后自动停止,不需要手动停止。
ContentProvider的作用
ContentProvider提供了一种在不同应用程序间共享数据的方式。它可以封装数据,并对外提供统一的访问接口。是多线程和多进程安全的,但具体实现时需要考虑线程同步问题。
Broadcast的注册方式
BroadcastReceiver可以通过两种方式注册:
- 在AndroidManifest.xml中静态注册。
- 在代码中动态注册。
静态注册的BroadcastReceiver即使应用没有运行,也可以接收到广播。动态注册的BroadcastReceiver只有在其注册的上下文(通常是Activity或Service)存在时才能接收广播。
广播可以是有序的也可以是无序的。有序广播(ordered broadcasts)可以被接收者中断,即一个接收者可以阻止进一步传播。无序广播(normal broadcasts)则不能被中断,所有注册了的接收者都会接收到。
AsyncTask的作用
AsyncTask用于在后台线程中执行短暂的任务,并可以在主线程中更新UI。它简化了线程和Handler的使用。AsyncTask的主要方法包括:
doInBackground(Params...):后台执行的任务。onPostExecute(Result):后台任务执行完后在主线程中执行。onProgressUpdate(Progress...):更新进度信息。
从Android 4.0开始,AsyncTask默认在一个单线程池中串行执行任务,但也可以通过executeOnExecutor方法在多线程池中并行执行。
PS:由于AsyncTask容易导致内存泄漏和对生命周期的管理不便,它在Android开发中逐渐被其他现代的异步处理方案所取代,如使用LiveData和ViewModel结合Kotlin Coroutines。
ViewModel
ViewModel是一个负责为UI准备数据的类,它能够管理界面相关的数据,并且能够在配置改变(如屏幕旋转)后继续存在。ViewModel的目的是从UI控制器中分离出数据获取的逻辑,使得数据可以持久化。
LiveData
LiveData是一个可观察的数据存储器类,它遵循观察者模式。与普通的观察者不同,LiveData是生命周期感知的,意味着它尊重Android组件(如Activity、Fragment)的生命周期,确保只有在组件处于活跃状态时才会通知数据变化。
Kotlin Coroutines
Kotlin Coroutines是一种轻量级的线程管理工具,它通过使用挂起函数来简化异步编程,让异步代码看起来更像是同步代码。它能够使代码非阻塞地执行,同时不会牺牲应用的性能。
结合使用
将LiveData、ViewModel和Kotlin Coroutines结合使用可以创建一个高效、易于维护和测试的数据流。
- ViewModel中通过Kotlin Coroutines启动异步任务获取数据。
- 数据获取:在ViewModel中使用Coroutines来异步获取数据,不会阻塞主线程。
- 数据更新:获取到数据后,使用
LiveData来存储这些数据。因为LiveData是生命周期感知的,所以它会在Activity或Fragment活跃时自动更新UI。 - UI观察LiveData:UI组件观察ViewModel中的LiveData,当数据发生变化时,UI会自动更新。
代码上,首先定义一个ViewModel,它包含LiveData来存储和管理UI相关数据
class MainViewModel : ViewModel() {private val _data = MutableLiveData<String>()val data: LiveData<String> = _datafun fetchData() {viewModelScope.launch {val result = withContext(Dispatchers.IO) { // 在IO线程中执行repository.getData()}_data.value = result }}
}
在Activity或Fragment中观察LiveData数据变化,并更新UI
class MainActivity : AppCompatActivity() {private val viewModel: MainViewModel by viewModels()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)viewModel.data.observe(this, Observer { data ->textView.text = data})viewModel.fetchData()}
}
相关文章:
Android开发 Activity启动模式、ViewModel与LiveData,及Kotlin Coroutines
目录 Activity启动模式 onNewIntent解释 Activity启动模式的考虑时机 Service启动模式 ContentProvider的作用 Broadcast的注册方式 AsyncTask的作用 ViewModel LiveData Kotlin Coroutines 结合使用 Activity启动模式 Android中Activity的启动模式有四种࿰…...
MQL语言实现抽象工厂模式
文章目录 一、定义抽象产品接口二、定义抽象工厂接口三、定义具体产品四、定义具体工厂五、定义工厂客户端六、客户端调用工厂客户端七、抽象工厂模式的结构 一、定义抽象产品接口 //------------------------------------------------------------------ //| participants …...
UE4开个头-简易小汽车
跟着谌嘉诚学的小Demo,记录一下 主要涉及到小白人上下车和镜头切换操作 1、动态演示效果 2、静态展示图片 3、蓝图-上下车...
Java基础入门day04
day04 包 包可以用来区分相同的类名 将相同的类放在不同包下,可以进行存储 一个目录下没有办法存在两个同名的文件 包最终在文件系统中与文件目录结构是一一对应的 在不同包下可以存放相同类名的文件 包后期还可以实现项目中模块的精确划分,controller,…...
中值定理j
f ( n ) ( ξ ) 0 f^{(n)}(\xi)0 f(n)(ξ)0...
第2篇【Docker项目实战】使用Docker部署Raneto知识库平台(转载)
【Docker项目实战】使用Docker部署Raneto知识库平台 一、Raneto介绍 1.1 Raneto简介 Raneto是一个免费、开放、简单的 Markdown 支持的 Node.js 知识库。 1.2 知识库介绍 知识库 知识库是指存储和组织知识的系统或库,它包括了各种类型的信息和知识,如…...
【Javascript】 Promise 对象(二)
【Javascript】 Promise 对象(一)-CSDN博客 Promise.all() Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。 const p Promise.all([p1, p2, p3]);上面代码中,Promise.all()方法接受一个数组作为参数&…...
细说C++反向迭代器:原理与用法
文章目录 一、引言二、反向迭代器的原理与实现细节三、模拟实现C反向迭代器反向迭代器模板类的设计反向迭代器的使用示例与测试 一、引言 迭代器与反向迭代器的概念引入 迭代器(Iterator)是C标准模板库(STL)中的一个核心概念&am…...
SpringBoot(依赖管理和自动配置)
文章目录 1.基本介绍1.springboot是什么?2.快速入门1.需求分析2.环境配置1.确认开发环境2.创建一个maven项目3.依赖配置 pom.xml4.文件目录5.MainApp.java (启动类,常规配置)6.HelloController.java (测试Controller&a…...
cad怎么转换成黑白的pdf图纸?分享3个常用的软件!
在工程设计、建筑、机械制造等领域,CAD图纸的应用非常广泛。然而,有时出于某些需要,我们可能需要将CAD图纸转换为黑白的PDF格式。那么,如何实现这一转换呢?本文将为您详细介绍几种常用的转换软件及其操作步骤。 迅捷CA…...
maven本地仓库依赖上传到远程仓库
本地仓库上传到远程仓库 批量上传: 批量本地仓库依赖(jar包)上传脚本: #!/bin/bash # copy and run this script to the root of the repository directory containing files # this script attempts to exclude uploading itse…...
ISIS多区域实验简述
为支持大型路由网络,IS-IS在路由域内采用两级分层结构。 IS-IS网络中三种级别的路由设备:将Level-1路由设备部署在区域内,Level-2路由设备部署在区域间,Level-1-2路由设备部署在Level-1和Level-2路由设备的中间。 实验拓扑图&…...
go语言基础笔记
1.基本类型 1.1. 基本类型 bool int: int8, int16, int32(rune), int64 uint: uint8(byte), uint16, uint32, uint64 float32, float64 string 复数:complex64, complex128 复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部…...
kettle 9.4和Pentoho 9.4下载及安装方法简介
kettle 9.4和Pentoho 9.4下载及安装方法简介 下载地址: https://sourceforge.net/projects/pentaho/files/ 下载步骤: #------------- 一、点击选项卡:summary/ 二、点击第一行链接 https://www.hitachivantara.com/en-us/products/pentaho…...
社交革命的引领者:探索Facebook如何改变我们的生活方式
1.数字社交的兴起 随着互联网的普及,社交媒体成为我们日常生活的重要组成部分。Facebook作为其中的先驱,从最初的社交网络演变成了一个拥有数十亿用户的全球化平台。它不仅改变了我们与世界互动的方式,还深刻影响了我们的社交习惯、人际关系以…...
常用的推荐算法
推荐系统在帮助用户发现可能感兴趣的产品、服务或信息方面发挥着重要作用。下面是一些常用的推荐算法: 1. 协同过滤 用户基于协同过滤(User-Based Collaborative Filtering) 基于用户之间的相似性为用户推荐物品。算法会找出与目标用户兴趣…...
使用Python进行图片格式转化/分辨率转化
一.下载python PIY插件库 PIP下载命令: pip install pillow -i https://mirrors.aliyun.com/pypi/simple PIY插件库:pillow Installation - Pillow (PIL Fork) 10.3.0.dev0 documentation 二.分辨率转化 from PIL import Image import osresolution (1024, 1024) with Image…...
植物神经功能紊乱患者每天从5片黛力新减少至2片,只因找对了治疗方法!
植物神经功能紊乱是一种常见的心理疾病,其症状包括焦虑、失眠、疲劳、头痛、胃肠不适等,给患者带来很大的困扰。然而,这种疾病是可以治疗的。本文将介绍一位植物神经功能紊乱患者的治疗经历,希望能够帮助更多的人了解和治疗此病。…...
SpringSecurity 快速入门
文章目录 1. 认证授权概述1.1 认证授权概念1.1.1 认证1.1.2 授权 1.2 权限数据模型1.3 RBAC权限模型1.3.1 介绍1.3.2 基于角色访问控制1.3.3 基于资源访问控制 1.4 常见认证方式1.4.1 Cookie-Session1.4.2 jwt令牌无状态认证 1.5 技术实现 2. SpringSecurity入门2.1 介绍2.2 入…...
MySQL--执行一条 select 语句,期间发生了什么?
执行一条 SQL 查询语句,期间发生了什么? 连接器:建立连接,管理连接、校验用户身份;查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;解析 …...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...
