开启Android学习之旅-3-Android Activity

Android Activity

本文总结《第一行代码 Android》第3版的内容

环境:
Android Studio Giraffe | 2022.3.1 Patch 3

Activity 是什么?

Activity 简单将就是UI界面,包含两部分 Activity 类 和应用布局文件,如果是 Compose 则另说,一般入门Android,都是从Activity开始的。
我们写一个程序,常常找应用启动入口,像 java 的 main()函数,那么 Activity 的应用入口在哪?下面通过创建项目认识。
在创建 Android 项目时,要选择 No Activity,是因为 Android Studio 2022 中如果选择 Empty Activity,会默认使用 Compose UI。在创建完成后,手动添加“Empty Activity”:
在这里插入图片描述
如果勾选 Launcher Activity,那么该 Activity 一般就是应用启动的时候,首先显示的。在这里插入图片描述
在创建 Activity 之后,会自动在 AndroidManifest 注册 Activity:
应用入口在 AndroidManifest.xml 中一般会有标识:

<activityandroid:name=".FirstActivity"android:launchMode="singleTask"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

Acttivity 的基本用法

在Android Studio 添加 Activity 之后,会创建两个文件:一个类,一个xml文件。类用来写逻辑,xml写UI布局。
修改 xml 布局,使用LinearLayout,默认的太复杂,添加 Button 控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".FirstActivity"><Buttonandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Button 1"/>
</LinearLayout>

然后在 Activity中添加逻辑:

// button 点击事件
button1.setOnClickListener{Toast.makeText(this,"你点击了按钮",Toast.LENGTH_SHORT).show()

一个最简单的应用就完成了。

使用 Toast 消息提示

Toast 用于提示用户,用法如上面,第三个参数有两种 Toast.LENGTH_SHORT 和 Toast.LENGTH_LONG,显示时长不一样。

Activity 界面添加 Menu

步骤1: 添加 Menu 资源文件
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/add_item"android:title="添加"/><itemandroid:id="@+id/remove_item"android:title="删除"/>
</menu>

步骤二:在 Activity中 重写 onCreateOptionsMenu() 方法

override fun onOptionsItemSelected(item: MenuItem): Boolean {when(item.itemId){R.id.add_item -> Toast.makeText(this,"添加菜单项",Toast.LENGTH_SHORT).show()R.id.remove_item -> Toast.makeText(this,"删除菜单项",Toast.LENGTH_SHORT).show()}return true}

效果:
在这里插入图片描述

销毁Activity

在按返回键时,Activity 可以被销毁,在代码中使用 finish() 方法

不同 Activity 中跳转

首先理解什么是 Intent?
在Android中,Intent是一种消息传递机制,用于在组件之间进行通信,如启动活动、启动服务、传递数据等。根据其使用方式,Intent可以分为显式Intent和隐式Intent。

显式Intent:显式Intent是指明确指定要启动的组件(如Activity、Service等)的名称。这种Intent通常用于应用内部的组件间通信。例如,从一个Activity启动另一个Activity。

val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)

在上述代码中,我们明确指定了要启动的Activity是SecondActivity,因此这是一个显式Intent。

FirstActivity 跳转到 SecondActivity 使用 显式 Intent。

隐式Intent:隐式Intent并没有明确指定要启动的组件,而是指定了一种动作(Action)和数据(Data),然后由系统解析这个Intent,找到合适的组件来处理这个Intent。这种Intent通常用于启动其他应用的组件。例如,打开网页、拨打电话等。

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.baidu.com")
startActivity(intent)

在上述代码中,我们指定了一个动作ACTION_VIEW和一个数据https://www.baidu.com,系统会找到能处理这个动作和数据的应用(如浏览器)来启动。因此这是一个隐式Intent。
如果让我们的程序能够响应隐式Intent,需要在 AndroidManifest.xml 中注册:

<activityandroid:name=".ThirdActivity"android:exported="true" ><intent-filter tools:ignore="AppLinkUrlError"><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/><data android:scheme="https"/></intent-filter></activity>

调用方法:

 // 隐式Intentval intent = Intent("com.alex.activitytest.ACTION_START")intent.addCategory("com.alex.activitytest.MY_CATEGORY")startActivity(intent)

不同Activity传递数据

FirstActivty 启动 SecondActivity 并传递数据:

  // 启动Activity并传递数据val data="Hello SecondActivity"val intent = Intent(this,SecondActivity::class.java)intent.putExtra("extra_data",data)startActivity(intent)

SecondActivity 接收数据:在 onCreate方法中

val extraData=intent.getStringExtra("extra_data")
Toast.makeText(this,extraData,Toast.LENGTH_SHORT).show()

如果 SecondActivity 需要向 FirstActivty 返回数据,需要三步,在 FirstActivty 调用的时候:把 startActivity(intent) 替换为

startActivityForResult(intent,1)

SecondActivity 返回数据:

val intent = Intent()
intent.putExtra("data_return","Hello, FirstActivity")
setResult(RESULT_OK,intent)
// 销毁当前Activity
finish()

FirstActivty 接收数据:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when (requestCode) {1 -> if (resultCode == RESULT_OK) {val returnedData = data?.getStringExtra("data_return")Log.d("FirstActivity", "returned data is $returnedData")}}
}

startActivityForResult 与 onActivityResult 被废弃了,可以参考这篇文章进行更新:

startActivityForResult被标记为废弃?Activity Result API闪亮登场!

Activity 生命周期

Android 使用 task 来管理 Activity,一个任务就是一组存放在返回栈里的 Activity的集合。启动Activity,Activity入栈,Activity销毁就会出栈。显示的Activity总是在栈顶。
在这里插入图片描述

Activity 的四种状态

  • 运行状态
    Activity处于栈顶
  • 暂停状态
    比如一个Activity上弹出一个对话框,此时Activity处于暂停状态
  • 停止状态
    Activity 不处于栈顶,并且完全不可见
  • 销毁状态
    Activity 从返回栈中移除

Activity 生命周期

  • onCreate()。会在Activity第一次被创建的时候调用。应该在这个方法中完成Activity的初始化操作,比如加载布局、绑定事件等。
  • onStart()。这个方法在Activity由不可见变为可见的时候调用。
  • onResume()。这个方法在Activity准备好和用户进行交互的时候调用。此时的Activity一定位于返回栈的栈顶,并且处于运行状态。
  • onPause()。这个方法在系统准备去启动或者恢复另一个Activity的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶Activity的使用。
  • onStop()。这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的Activity,那么onPause()方法会得到执行,而onStop()方法并不会执行。
  • onDestroy()。这个方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
  • onRestart()。这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

在这里插入图片描述
结合GPT,谈谈应用场景:
onCreate():
应用场景: 初始化 Activity,设置布局,初始化成员变量和数据绑定。
例子: 在一个音乐播放器应用中,在 onCreate() 中加载布局,初始化播放控制按钮和音轨信息。

onStart():
应用场景: 让 Activity 对用户可见,进行一些轻量级的资源初始化或恢复操作。
例子: 在新闻应用中,当 Activity 变为可见时,可以在 onStart() 中开始加载新闻列表。

onResume():
应用场景: 当 Activity 与用户交互前,恢复暂停的动画,初始化相机等。
例子: 在相机应用中,在 onResume() 方法中打开相机预览。

onPause():
应用场景: 暂停或调整不再需要的操作,如暂停动画,释放相机资源。
例子: 如果用户在编辑照片的应用中接到电话,onPause() 可用于暂停编辑进度或保存状态。

onStop():
应用场景: 当 Activity 不再可见时,释放或调整资源和操作,如停止播放媒体,取消网络请求。
例子: 在视频播放应用中,当用户离开播放界面,可以在 onStop() 中停止视频播放并释放播放器资源。

onDestroy():
应用场景: 清理资源,如关闭数据库连接,注销广播接收器。
例子: 在社交应用中,当 Activity 销毁时,关闭数据库连接和注销监听网络变化的广播接收器。

onRestart():
应用场景: 在 Activity 从停止状态回到活动状态时调用,用于重新初始化在 onStop() 中释放的资源。
例子: 在购物应用中,如果用户从购物车界面切换到其他应用然后返回,可以在 onRestart() 中刷新购物车数据。

如果从网络请求新闻列表数据,可以写在 onStart 或 onResume 方法中。如果你希望每次 Activity 变得可见时都刷新数据,那么 onStart() 是合适的地方。如果你希望在 Activity 每次回到用户交互前台时刷新数据,则 onResume() 更为合适。此外,考虑到网络请求可能会耗时并影响用户体验,推荐使用异步处理(如使用 AsyncTask 或 Retrofit 等网络库)来进行网络请求,避免阻塞主线程。

Activity 保存状态数据

如果 Activity 在停止状态时,有可能被回收,再返回时,如果没有数据,Activity可能无法正常显示,此时需要保存状态,可以使用 onSaveInstanceState方法,确保在回收前保存

override fun onSaveInstanceState(outState: Bundle) {super.onSaveInstanceState(outState)val tempData = "Something you just typed"outState.putString("data_key", tempData)
}

在onCreate() 恢复数据:

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)Log.d(tag, "onCreate")setContentView(R.layout.activity_main)if (savedInstanceState != null) {val tempData = savedInstanceState.getString("data_key")Log.d(tag, "tempData is $tempData")}...
}

Activity 四种启动模式

Android 中Activity的四种启动模式及使用场景如下:

  1. Standard

用途: 每次启动 Activity 时都会创建一个新的实例,无论该 Activity 是否已经存在于任务栈中。

应用场景: 这是默认模式。适用于大多数标准的 Activity,如显示列表项的详细信息。例如,在邮件应用中,用户点击一个邮件时,每次都会创建一个新的邮件详情 Activity,即使是同一个邮件。

在这里插入图片描述
2. SingleTop

用途: 如果新的 Activity 已经是任务栈的顶端,则不会创建新的实例,而是复用栈顶的实例,并通过 onNewIntent() 方法接收新的 Intent。

应用场景: 适用于需要接收新信息且频繁启动但不需要多实例的 Activity。例如,在聊天应用中,如果用户已经在聊天界面,新消息的通知点击后只更新当前的聊天界面,而不重新创建 Activity。
在这里插入图片描述

  1. SingleTask

用途: 只创建一个实例,该实例会在新的任务栈中。如果 Activity 已经存在,则把这个 Activity 之上的所有其他 Activity 出栈,使这个 Activity 显示在最前。

应用场景: 适用于作为应用中单一入口的 Activity,如主页。例如,在浏览器应用中,主页 Activity 设置为 singleTask,无论从哪里启动,都只有一个主页实例。
在这里插入图片描述
4. SingleInstance

用途: 类似于 singleTask,但系统会为这种 Activity 创建一个新的任务栈,并且在这个栈中只有这个 Activity 实例。

应用场景: 适用于需要与应用完全分离的模块,例如,一个应用内的浮动小窗口或者是需要与其他应用共享的 Activity。例如,一款具有浮动小窗功能的音乐播放器,其播放控制界面可以设置为 singleInstance 模式。
举例:

Activity最佳实践

通过BaseActivity知晓当前在哪一个Activity

open class BaseActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)Log.d("BaseActivity", javaClass.simpleName)}
}

全局管理Activity,随时退出程序

新建单例类ActivityCollector

package com.alex.activitytest
import android.app.Activity/*** @Author      : alex* @Date        : on 2023/12/28 15:59.* @Description :描述*/
object ActivityCollector {private val activities = ArrayList<Activity>()fun addActivity(activity: Activity){activities.add(activity)}fun removeActivity(activity: Activity){activities.remove(activity)}fun finishAll(){for(activity in activities){if(!activity.isFinishing){activity.finish()}}activities.clear()}
}

这个方法在测试的时候不行,比如点击按钮执行 ActivityCollector.finishAll(), 系统会重启App,即时加了下面的代码也一样。

android.os.Process.killProcess(android.os.Process.myPid())

可参考:https://blog.csdn.net/shulianghan/article/details/116402759

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DS|图(连通与生成树)

题目一&#xff1a;DS图 -- 图的连通分量 题目描述&#xff1a; 输入无向图顶点信息和边信息&#xff0c;创建图的邻接矩阵存储结构&#xff0c;计算图的连通分量个数。 输入要求&#xff1a; 测试次数t 每组测试数据格式如下&#xff1a; 第一行&#xff1a;顶点数 顶点…

【Linux进程】 进程的理解

目录 前言 1. 系统管理 2. 进程 2.1 概念 2.2 进程的调度 2.3 描述进程-PBC 3. 查看进程 4. 通过系统调用获取进程标示符 前言 在计算机科学领域&#xff0c;进程是一种重要的概念&#xff0c;在日常学习中也经常遇到进程这个概念&#xff0c;那么进程到底是什么&#x…

tkinter实现一个简易窗口

tkinter目录 1. 最简易的窗口2. 加了标签、按钮、输入框&#xff0c;并且按钮连接了函数 1. 最简易的窗口 import tkinter as tkwindow tk.Tk()window.title(我的窗口) # 设置窗口名 window.geometry(500x300) # 设置窗口长宽label tk.Label(window, text文字文字文字, bg…

Vue3中使用动态组件

文章目录 使用方式&#xff1a;使用场景&#xff1a; 在 Vue 3 中&#xff0c;动态组件是一种允许在运行时动态切换组件的机制。Vue 3 提供了 元素以及 is 特性来实现动态组件的切换。 使用方式&#xff1a; 1、使用 元素 在模板中使用 元素&#xff0c;通过 is 特性来动态切换…

CSS基础笔记-01CSS概述

文章目录 前言CSS是什么CSS的作用CSS语法添加CSS的方法 前言 CSS是什么&#xff1f;有什么作用&#xff1f;怎么编写CSS&#xff1f;怎样添加CSS&#xff1f;本文对CSS的四个方面作了学习并形成学习笔记。 CSS是什么 CSS &#xff08;Cascading Style Sheets&#xff0c;层叠…

CentOS 多节点一键免密登录

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

解决2023新版Edge浏览器页面加载不出来问题

2023年推出的新版Edge浏览器为用户带来了更好的性能和用户体验。然而&#xff0c;有一些用户反馈称他们在使用新版Edge浏览器时遭遇了页面加载不出来的问题。本篇博客将详细介绍如何解决这个问题&#xff0c;以确保您能够顺畅地使用新版Edge浏览器浏览网页。 1、清除缓存和Coo…

使用 Python 进行贝叶斯优化

一、介绍 贝叶斯优化是一种先进的技术&#xff0c;用于优化评估成本高昂的函数。该策略为全局优化提供了原则性策略&#xff0c;强调探索&#xff08;尝试新领域&#xff09;和开发&#xff08;尝试看起来有前途的领域&#xff09;之间的平衡。 二、什么是贝叶斯优化&#xff1…

Mysql 分割字符串,一行变多行,@rownum,mysql.help_topic

1 前言 朋友最近遇到一个比较棘手的 sql 问题&#xff0c;让我帮忙看看&#xff1a; 他有两张表 testa 和 testb &#xff0c;一个表存的日期&#xff0c;另一个表存字符串例如 2023-11-01,2023-11-02&#xff0c;如何将这两张表关联起来&#xff0c;只查 testa 表的数据&#…

streamlit 入门demo

一、介绍 Streamlit 是一个用于创建数据应用程序的 Python 库&#xff0c;它致力于简化从数据脚本到可部署应用程序的整个过程。通过 Streamlit&#xff0c;你可以使用熟悉的 Python 语言创建交互式的、美观的数据应用&#xff0c;而无需深入了解前端开发。 二、优势和特点 简…

分布式基础概念

分布式基础概念 1 微服务 微服务架构风格&#xff0c;就像是把一个单独的应用程序开发为一套小服务&#xff0c;每个小服务运行在自己的进程中&#xff0c;并使用轻量级机制通信&#xff0c;通常是HTTP API。这些服务围绕业务能力来构建&#xff0c;并通过完全自动化部署机制…

AUTOSAR从入门到精通-漫谈autosar软件架构(七)

目录 前言 原理 AUTOSAR软件开发现状 Autosar分层架构 基础软件层(BSW)

【Path的使用】Node.js中的使用Path模块操作文件路径

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;Node.js &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继续前进的勇…

Jenkins集成部署java项目

文章目录 Jenkins简介安装 Jenkins简介 Jenkins能实时监控集成中存在的错误&#xff0c;提供详细的日志文件和提醒功能&#xff0c;还能用图表的形式形象的展示项目构建的趋势和稳定性。 官网 安装 在官网下载windows版本的Jenkins 但是我点击这里浏览器没有反应&#xff0…

Vue3-38-路由-路由的懒加载

什么是路由的懒加载 一句话概括 &#xff1a; 懒加载&#xff0c;就是在初次用到的时候才执行加载&#xff1b;而非一上来就全部加载完毕。优点 &#xff1a; 可以提高项目的访问效率。因为一上来不用加载所有的资源。建议 &#xff1a; 项目中的所有路由配置都配置为 懒加载…

使用 KubeSphere 与极狐GitLab 打造云原生持续交付系统

极狐GitLab 简介 极狐GitLab 是一个一体化的 DevOps 平台&#xff0c;可以简单理解为 GitLab 在国内的“发行版”。是由极狐(GitLab)公司推出的产品&#xff08;极狐(GitLab)公司是以“中外合资3.0”模式成立的公司&#xff0c;在国内独立运营&#xff0c;为国内用户提供适合本…

test mutation-00-变异测试概览

拓展阅读 test 系统学习-04-test converate 测试覆盖率 jacoco 原理介绍 test 系统学习-05-test jacoco 测试覆盖率与 idea 插件 test 系统学习-06-test jacoco SonarQube Docker learn-29-docker 安装 sonarQube with mysql Ubuntu Sonar 突变测试是什么&#xff1f; …

2024你好!

在刚刚过去的一年里&#xff0c;科技行业犹如璀璨的星辰照亮了全球的进步之路。特别是在人工智能的疆域中&#xff0c;大模型技术犹如破晓的曙光&#xff0c;以其数十亿乃至千亿级别的参数力量&#xff0c;掀起了前所未有的变革浪潮。 2023年&#xff0c;大模型技术无疑成为了人…

谷歌浏览器启用实时字幕功能

在 Chrome 中使用“实时字幕”功能 - Google Chrome帮助 在 Chrome 中使用“实时字幕”功能 从计算机上的 Chrome 浏览器中&#xff0c;您可以使用“实时字幕”功能自动为视频、播客、游戏、直播、视频通话或其他音频媒体生成字幕。音频和字幕均在本地处理&#xff0c;并会保…

K8S学习指南(64)-K8S源代码走读之Kubelet

文章目录 前言Kubelet 的代码结构Kubelet 的核心逻辑1. Pod 生命周期管理1.1 Pod 启动逻辑1.2 Pod 状态管理1.3 Pod 事件处理 2. 容器启动和监控2.1 容器启动逻辑2.2 容器监控 3. 容器网络和存储3.1 容器网络3.2 容器存储 4. 资源管理4.1 资源分配 5. 启动和注册 Kubelet5.1 启…