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

news2024/11/16 9:44:47

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 中一般会有标识:

<activity
            android: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">
    <Button
        android: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">
    <item
        android:id="@+id/add_item"
        android:title="添加"/>
    <item
        android: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 中注册:

<activity
            android: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>

调用方法:

 // 隐式Intent
 val 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.coloradmin.cn/o/1360342.html

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

相关文章

kubernetes(一)概述与架构

云原生实战 语雀 官网 Kubernetes 文档 | Kubernetes 更新&#xff1a;移除 Dockershim 的常见问题 | Kubernetes B站课程&#xff1a;https://www.bilibili.com/video/BV13Q4y1C7hS/?p26 1.概述 概述 | Kubernetes 大规模容器编排系统 kubernetes具有以下特性&#xf…

【数值分析】非线性方程求根,牛顿法,牛顿下山法,matlab实现

4. 牛顿法 收敛时牛顿法的收敛速度是二阶的&#xff0c;不低于二阶。如果函数有重根&#xff0c;牛顿法一般不是二阶收敛的。 x k 1 x k − f ( x k ) f ′ ( x k ) x_{k1}x_k- \frac{f(x_k)}{f(x_k)} xk1​xk​−f′(xk​)f(xk​)​ matlab实现 %% 牛顿迭代例子 f (x) x…

x-cmd pkg | gh - GitHub 官方 CLI

目录 简介首次用户功能特点与 x-cmd gh 模块的关系相关作品进一步探索 简介 gh&#xff0c;是由 GitHub 官方使用 Go 语言开发和维护的命令行工具&#xff0c;旨在脚本或是命令行中便捷管理和操作 GitHub 的工作流程。 注意: 由于 x-cmd 提供了同名模块&#xff0c;因此使用官…

机器视觉系统选型-环境配置:报错序列不包含任何元素 的解决方法

描述 环境&#xff1a;VM4.0.0VS2015 及以上 现象&#xff1a;配置环境后&#xff0c;获取线线测量模块结果&#xff0c;报错“序列不包含任何元素”。如下图所示&#xff1a; 解答 将“\VisionMaster4.0.0\Development\V4.0.0 \ComControls\bin\x64”下整体重新拷贝。

StreamPark + PiflowX 打造新一代大数据计算处理平台

&#x1f680; 什么是PiflowX PiFlow 是一个基于分布式计算框架 Spark 开发的大数据流水线系统。该系统将数据的采集、清洗、计算、存储等各个环节封装成组件&#xff0c;以所见即所得方式进行流水线配置。简单易用&#xff0c;功能强大。它具有如下特性&#xff1a; 简单易用…

在云服务器ECS上用Python写一个搜索引擎

在云服务器ECS上用Python写一个搜索引擎 一、场景介绍二、搜索引擎的组成2.1 网页的爬取及排序2.2 用户使用搜索引擎进行搜索 三、操作步骤3.1 环境准备3.2 安装Anaconda3.3 安装Streamlit3.4 下载搜索引擎代码3.5 运行搜索引擎 四、常见问题4.1 运行setup.py时可能的问题4.2 如…

oracle 补齐数字长度 to_char踩坑

oracle的to_char网上找到的说明如下 &#xff08;1&#xff09;用作日期转换&#xff1a; to_char(date,格式); select to_date(2005-01-01 ,yyyy-MM-dd) from dual; select to_char(sysdate,yyyy-MM-dd HH24:mi:ss) from dual; &#xff08;2&#xff09;处理数字&#xf…

unity PDFRender Curved UI3.3

【PDF】PDFRender 链接&#xff1a;https://pan.baidu.com/s/1wSlmfiWTAHZKqEESxuMH6Q 提取码&#xff1a;csdn 【曲面ui】 Curved UI3.3 链接&#xff1a;https://pan.baidu.com/s/1uNZySJTW0-pPwi2FTE6fgA 提取码&#xff1a;csdn

【软件测试】2024年准备中/高级测试岗技术面试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试基础知…

Netplan介绍

1 介绍 1.1 简介 Netplan是一个抽象网络配置描述器。通过netplan命令&#xff0c;你只需用一个 YAML文件描述每个网络接口所需配置。netplan并不关系底层管理工具是NetworkManager还是networkd。 它是一个在 Linux 系统上进行网络配置的实用程序。您创建所需接口的描述并定义…

【动态规划】【字符串】132.分割回文串 II

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 动态规划 字符串 LeetCode132. 分割回文串 II 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1&#xff1a; 输入&#x…

阿里云服务器配置jupyter(新手入门,详细全面)

设置安全组 1.租好服务器后在阿里云服务器平台上打开控制台&#xff08;右上角&#xff09; 2.点开自己的云服务器控制台&#xff0c;在左栏“安全组”部分添加安全规则&#xff0c;点击“管理规则” 单击“手动添加”&#xff0c;将安全组设为如下格式&#xff0c;端口范围…

wsl(ubuntu)创建用户

我们打卡ubuntu窗口&#xff0c;如果没有创建用户&#xff0c;那么默认是root用户 用户的增删改查 查 查询所有的用户列表 cat /etc/passwd | cut -d: -f1cat /etc/passwd: 这个命令用于显示 /etc/passwd 文件的内容。/etc/passwd 文件包含了系统上所有用户的基本信息。每一…

UG装配-沿线运动

如果希望图中圆柱销沿着槽运动&#xff0c;直接约束面是困难的&#xff0c;我们可以画出圆弧的中心线和圆柱销的中心点&#xff0c;约束点在线上&#xff0c;进行移动 需要注意的是&#xff0c;我们在零件中画点和线的时候&#xff0c;在装配体默认加载模型引用集的时候是无法显…

如何通过HACS+Cpolar实现远程控制米家和HomeKit等智能家居设备

文章目录 基本条件一、下载HACS源码二、添加HACS集成三、绑定米家设备 ​ 上文介绍了如何实现群晖Docker部署HomeAssistant&#xff0c;通过内网穿透在户外控制家庭中枢。本文将介绍如何安装HACS插件商店&#xff0c;将米家&#xff0c;果家设备接入 Home Assistant。 基本条件…

leetcode:908. 最小差值 I

一、题目 二、函数原型 int smallestRangeI(int* nums, int numsSize, int k) 三、思路 本题题目有些绕口&#xff0c;但是无伤大雅。本质就是可以对数组中的每个元素进行加/减 k 的操作&#xff0c;然后求数组中的最大、最小元素的最小差值。 分为几种情况&#xff1a; …

【数据库系统概论】数据库并发控制机制——并发操作带来的数据不一致性问题有哪些

系统文章目录 数据库的四个基本概念&#xff1a;数据、数据库、数据库管理系统和数据库系统 数据库系统的三级模式和二级映射 数据库系统外部的体系结构 数据模型 关系数据库中的关系操作 SQL是什么&#xff1f;它有什么特点&#xff1f; 数据定义之基本表的定义/创建、修改和…

若依前后端分离版关联字典值查询数据工具类使用

场景 若依管理系统导出Excel时添加没有的列和关联码表显示中文进行导出&#xff1a; 若依管理系统导出Excel时添加没有的列和关联码表显示中文进行导出_若依的导出添加额外的字段信息-CSDN博客 上面通过关联表的方式实现查询字典值&#xff0c;若依本身提供了查询redis中缓存…

【数据库原理】(10)数据定义功能

SQL 数据定义功能包括定义模式、定义表、定义索引和定义视图,其语句如表所示。 一.创建、删除模式 1.创建模式 (Create Schema) 用途&#xff1a;创建模式是为了在数据库中定义一个新的命名空间&#xff0c;它可以包含多个数据库对象。 语法&#xff1a; CREATE SCHEMA &…

建站指南,如何将拥有的域名自定义链接到wordpress

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 在Dynadot上&#xff0c;我们可已经账户中管理的…