《第一行代码》核心知识点:Activity(活动)

news2025/1/15 13:17:25

Android四大组件之一:Activity

  • 前言
  • 二、Android四大组件之一:Activity(活动)
    • 2.1 活动基本介绍
    • 2.2 活动的基本用法
      • 2.2.1 如何在应用中弹出提示信息
      • 2.2.2 如何在活动中添加Menu菜单(就一般右上角的三点)
      • 2.2.3 如何实现活动跳转
      • 2.2.5 如何实现向下一个活动传递数据
      • 2.2.5 如何实现向上一个活动返回数据
      • 2.2.6 如何销毁一个活动
    • 2.3 活动的生命周期
      • 2.3.1 返回栈
      • 2.3.2 活动生命周期中的4种状态
      • 2.3.3 活动生命周期内各个阶段的回调函数
      • 2.3.4 如果活动被系统回收了,还想保留活动的数据,该怎么办?
    • 2.4 活动的启动模式
      • 2.4.1 standard
      • 2.4.2 singleTop
      • 2.4.3 singleTask
      • 2.4.4 singleInstance
    • 2.5 使用活动的小技巧
  • 参考书籍:第一行代码

前言

本文讲解Android四大组件之一(活动)的基本用法,生命周期,启动模式等。

二、Android四大组件之一:Activity(活动)

2.1 活动基本介绍

活动是一种包含用户界面的组件,主要用于和用户进行交互。简单来说,一个活动就对应一个交互窗口。

2.2 活动的基本用法

2.2.1 如何在应用中弹出提示信息

Toast类下的静态方法makeText 可以在应用上弹出一个简单的提示信息,这是Android开发中比较常用的提示方法。

public static Toast makeText (Context context, //The context to use. Usually your Application or Activity object.
                int resId, //可以字符串资源ID,也可以直接输入提示文本字符串
                int duration)//信息显示时间: Either LENGTH_SHORT or LENGTH_LONG

示例代码

Toast.makeText(SecondActivity.this, "这是一条信息提示", Toast.LENGTH_SHORT).show();

在一个SecondActivity活动的程序中弹出一条信息提示。
在这里插入图片描述

2.2.2 如何在活动中添加Menu菜单(就一般右上角的三点)

  1. 右键res,新建menu类型资源文件夹
    在这里插入图片描述
    在这里插入图片描述
  2. 右键刚刚新建的menu文件夹,创建Menu资源文件
    在这里插入图片描述
  3. 在menu资源文件xml中编写菜单栏项目,示例代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/add"
    android:title="添加"/>
    <item
        android:id="@+id/remove"
        android:title="移除"/>
</menu>
  1. 重写onCreateOptionsMenu方法,通过getMenuInflater().inflate加载我们刚刚创建的menu资源,注意,最后要返回true才能显示我们的menu
 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }
  1. 此时运行程序,就可以看到右上角有三个点,点击就可以看到我们设置的菜单项
    在这里插入图片描述
    在这里插入图片描述
  2. 通过重写onOptionsItemSelected方法,为每个菜单项添加点击事件
@Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId())
        {
            case R.id.add:
                Toast.makeText(this, "点击了add菜单项", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove:
                Toast.makeText(this, "点击了remove菜单项", Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }

2.2.3 如何实现活动跳转

一个活动对应一个交互界面,而一个app往往包含很多个交互界面,因此如何实现从一个交互界面(活动)跳转到另一个交互界面呢?

  1. 方式一、显示Intent
    从活动FirstActivity跳转到活动SecondActivity,使用显示Intent方式实现的示例代码如下
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
  • 首先通过构造函数实例化Intent,构造函数第一个参数当前活动的上下文,第二个参数是你要跳转到活动的class对象。
  • 其次调用startActivity方法实现活动之间的跳转。
  1. 方式二、隐示Intent
    从活动FirstActivity跳转到活动SecondActivity,使用隐示Intent方式实现的示例代码如下
  • 首先为SecondActivity在manifest文件中的 activity标签添加intent-filter标签
  <activity
            android:name=".SecondActivity"
            android:launchMode="singleInstance"
            android:label="这是第二个活动"
            android:exported="false">
            <intent-filter>
                <!-- 当前活动可以响应的标签 -->
                <action android:name="com.example.activitytest.ACTION_START" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MY_CATEGORY" />
            </intent-filter>
        </activity>
  • 其次在实例化intent对象时,将action的name字符串传入构造函数,并通过addCategory方法将xml中配置的category全部一一对应的添加进去,最后调用startActivity实现活动的跳转。
Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("android.intent.category.DEFAULT");//DEFAULT可以省略
intent.addCategory("android.intent.category.MY_CATEGORY");
startActivity(intent);

显式Intent多方便呀,为啥要用隐式Intent呢?又要配置manifest,又要多写代码。
因为,使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。

比如我采用隐式Intent启动一个网页活动,示例代码如下:

Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);

比如我采用隐式Intent启动给10086打电话的界面,示例代码如下:

Intent intent=new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

2.2.5 如何实现向下一个活动传递数据

Intent的putExtra方法可以实现以键值对的形式将数据传递给下一个活动,如从FirstActivity传递数据到SecondActivity的示例代码如下:

Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("key","第一个活动窗口数据");
startActivity(intent)

如从SecondActivity获取FirstActivity传递的数据的示例代码如下:

Intent intent = getIntent();
String key = intent.getStringExtra("key");

2.2.5 如何实现向上一个活动返回数据

如从活动FirstActivity跳转到活动SecondActivity,想要将SecondActivity处理好的数据返回给FirstActivity的示例代码如下:

  1. 采用startActivityForResult跳转活动
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);//第二个参数是请求码,用于标识回调数据的来源*/
  1. 通过setResult方法将数据返回给上一个活动FirstActivity
Intent intent=new Intent();
intent.putExtra("return_data","【onCreate】你好,我是第二个和活动");
setResult(RESULT_OK,intent);
  1. FirstActivity活动重写onActivityResult方法,获取SecondActivity返回的数据
    //requestCode是FirstActivity传入的请求码:1,resultCode是SecondActivity传入的请求码:RESULT_OK,data是返回的数据
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    String return_data = data.getStringExtra("return_data");
                    Log.d(TAG, return_data);
                }
                break;
            default:
                break;
        }
    }

2.2.6 如何销毁一个活动

销毁一个活动非常简单,只需要在本活动调用 finish()方法即可。

2.3 活动的生命周期

2.3.1 返回栈

理解活动的生命周期,首先要明白活动的返回栈。因为多个活动是可以叠加的,用户只能看到最上面的活动,我们每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键,会销毁最上面的活动,这时下面的一个活动就会显示出来。很明显,活动的操作与数据结构中后进先出的“栈”极其吻合,而Android是使用任务来管理活动的,一个任务就是存放在栈里的活动的集合,这个栈就称为返回栈
在这里插入图片描述

2.3.2 活动生命周期中的4种状态

  1. 运行状态
    活动位于返回栈的栈顶时,这时活动就处于运行状态系统一般不会回收处于运行状态的活动。
  2. 暂停状态
    活动不再处于栈顶位置,但是仍然可见时,这时活动就进入了暂停状态。因为并不是每个活动都占满屏幕的,比如一个对话框形式的活动只会占用屏幕中间的部分,那么它后面的部分可见的活动就是处于暂停状态。系统一般不会回收暂停状态的活动,除非内存极其紧张的情况下。
  3. 停止状态
    当活动不再处于栈顶位置,并且完全不可见时,就进入了停止状态。当其他地方需要内存时,系统可能会回收停止状态的活动。
  4. 销毁状态
    当活动从返回栈中移除时后,就会变成销毁状态系统会优先回收处于销毁状态额活动,从而保证手机内存充足。

从上面可以看出,这四种状态最大的区别是,系统回收这四种状态活动所占用内存的优先级不同,从高到低依次是:销毁状态,停止状态,暂停状态,运行状态。

2.3.3 活动生命周期内各个阶段的回调函数

活动的整个生命周期可以划分为三种生存期,如下图所示。
在这里插入图片描述

  • onCreate():它会在活动第一次被创建的时候调用,该方法在 Activity 的整个生命周期中只应发生一次。可以在该方法中完成一些初始化操作,如加载布局,绑定事件等。
  • onStart():这个方法在活动由不可见变为可见的时候调用
  • onResume():这个方法在活动准备好与用户进行交互的时候调用。此时的活动一定处于返回栈的栈顶,并且处于运行状态。
  • onPause():这个方法在系统准备去启动或者恢复另一个活动的时候调用。通常会在这个方法中将一些消耗CPU的资源释放掉,以保存一些关键数据。
  • onStop():这个放在活动完全不可见的时候调用。它和onPause的主要区别在于,如果启动的新活动是一个对话框式的活动 [1],那么onPause方法会得到执行,而onStop方法不会执行,因为对话框式的活动并不会占满整个屏幕,上一个活动仍然部分可见。
  • onDestory():这个方法在活动销毁之前调用,之后活动的状态将会变为销毁状态。
  • onRestart():这个方法在活动由停止状态变为运行状态之前调用。一般是用户按下返回键的时候,一个停止状态的活动就会变为运行状态。

[1] 小知识:如何设计一个对话框式的活动呢?
我们只需要在AndroidManifest.xml文件中对应活动的Activity标签中添加android:theme=“@android:style/Theme.Dialog” 属性即可。
示例:

 <activity
	android:name=".DialogActivity"
	android:theme="@android:style/Theme.Dialog"/>

2.3.4 如果活动被系统回收了,还想保留活动的数据,该怎么办?

比如用户在活动A的基础上启动了活动B,那么活动A就会进入停止状态,而停止状态的活动很有可能因内存紧张被系统回收,导致用户从B返回A的时候,发现A活动上的原本输入的数据都没了(因为系统因内存不足回收掉A活动后,用户再返回活动A就要重写通过onCreate方法重新创建活动),这对于用户是不友好的。

因此Activity提供了onSaveInstanceState()回调方法,该方法保证活动被回收之前一定被调用,因此,用户可以在该方法中保存一些避免因活动被系统回收而导致丢失的必要数据。onSaveInstanceState方法传入的参数带有一个Bundle类型的参数,用户可以通过Bundle数据结构保存数据,然后这个Bundle数据会被传入在onCreate()方法中,用户可以在onCreate中获取Bundle中保存的数据。

//系统回收活动前调用该方法
protected void onSaveInstanceState(@NonNull Bundle outState) {//...}
//活动创建时调用该方法,savedInstanceState是由outState传入
protected void onCreate(Bundle savedInstanceState) {//...}

2.4 活动的启动模式

活动的启动模式一共有四种,可以通过< Activity >标签指定android:launchMode属性选择启动模式。

android:launchMode=["standard" | "singleTop" |
                              "singleTask" | "singleInstance" | "singleInstancePerTask"]

2.4.1 standard

standard模式是活动的默认启动模式。使用standard模式启动的活动,系统不管这个活动是否已经存着返回栈中,每次启动都会创建一个新的活动实例。
在这里插入图片描述

2.4.2 singleTop

使用singleTop模式启动活动,系统会先判断返回栈的栈顶是否存着该活动,若存在,则直接使用栈顶的活动,不会再创建新的活动实例。如果活动存在,但并不在返回栈的栈顶,系统仍然会创建新的活动实例。

2.4.3 singleTask

singleTop模式可以解决重复创建返回栈栈顶活动的问题,但如果活动没有处在栈顶位置,还是会出现重复创建的问题,那么singleTask模式就可以保证某个活动在整个应用程序中只存在一个实例
使用singleTask模式启动的活动,系统会首先在返回栈中查找是否已经存在该活动,若存在,则使用该活动,并把返回栈中该活动之上的所有活动全部出栈;若不存在,则创建一个新的活动实例。

2.4.4 singleInstance

使用singleInstance模式启动的活动,会在一个新的返回栈中管理该活动
如我们设计FirstActivity、SecondActivity、ThirdActivity三个活动,并将SecondActivity设置为singleInstance启动模式,我们首先从FirstActivity中启动SecondActivity活动,然后从SecondActivity中启动ThirdActivity活动,返回栈示意图如下。SecondActivity会启用一个单独的返回栈管理该活动,当用户点返回键会直接回到FirstActivity,然后再点击返回键,才会回到SecondActivity。
在这里插入图片描述

2.5 使用活动的小技巧

我们可以设计一个活动基类,并在这个基类的onCreate方法中打印类名,也可以在这个方法中收集活动实例,在onDestory方法中移除活动实例。然后其它活动都继承这个基类活动,这样我们就能获取当前活动的类名,并且收集所有现存活动的实例,以便在任何位置关闭所有活动实现程序退出,而不必一次次点击back键。
示例代码:

public class BaseActivity extends AppCompatActivity {
    private static final String TAG = "BaseActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, getClass().getSimpleName());//打印活动名
        ActivityCollector.addActivity(this);//收集启动的活动实例
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);//移除销毁的活动实例
    }
}

参考书籍:第一行代码

链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag

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

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

相关文章

CANoe-什么是Vector Tool Platform(全网唯一讲明白的文章)

在CANoe软件:Home -> Measurement下,有一个功能项,Vector Tool Platform,是做什么用的呢? 点击后打开这个功能页面,发现界面内容不多,包含:设备选择、组件更新、系统更新、远程连接,还有一个连接状态显示 从界面功能猜测:这是一个设备管理和连接的平台。那么是什么…

购买窗帘时哪些可以不做?-江南爱窗帘十大品牌

在家居软装上&#xff0c;窗帘的选择很重要&#xff0c;因为它的存在感很强&#xff0c;占据了墙面的半壁江山。选对了&#xff0c;满心欢喜&#xff0c;选错了&#xff0c;就只能悔恨痛苦了。 1.不做拼色、花纹&#xff1a;拼色窗帘在酒店十分常见&#xff0c;但是不建议照搬回…

14 C++11线程同步之条件变量

在学习条件变量之前需要先了解下std::unique_lock;条件变量 condition_variable需要配合std::unique_lock使用&#xff1b; std::unique_lock std::unique_lock的详细细节参考此篇文章。 C11条件变量 条件变量是 C11 提供的另外一种用于等待的同步机制&#xff0c;它能阻塞…

第04章_运算符

第04章_运算符 1. 算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&…

使用dbeaver连接GaussDB数据库(集中式)

服务端方式登录 默认初始用户登录方式&#xff1a; [ommgaussdb01 ~]$ gsql -d postgres -p 30100 gsql ((GaussDB Kernel V500R002C10 build 04860477) compiled at 2022-10-28 20:04:35 commit 3892 last mr 8894 release) Non-SSL connection (SSL connection is recommen…

XAML标记扩展(3)

一、RelativeSource属性 我们进行Bingding时&#xff0c;如果明确知道数据源的Name&#xff0c;就能用Source或者ElementName进行绑定&#xff0c;但是有时候我们需要绑定的数据源可能没有明确的Name&#xff0c;此时我们就需要利 用Bingding的RelativeSource进行绑定&#xf…

虚拟数字人/直播/捏脸/3D/metahuman 实时人脸动作捕捉 开发笔记

拍照生成数字人 流程 手机&#xff08;iphone xr以上&#xff09;拍照&#xff08;脸部&#xff09;&#xff0c;导入到unrealmetahuman做数字人 【中文】从0开始捏一个自己的虚拟人&#xff0c;手机扫描到MetaHuman做一个自己的虚拟人_哔哩哔哩_bilibili 涉及APP iphone …

[附源码]java毕业设计校园兼职招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

YUV图像基础知识

概念 YUV和RGB的功能类似&#xff0c;都是用来表示图像色彩的。但是对于 YUV 所表示的图像&#xff0c;Y 和 UV 分量是分离的。如果只有 Y 分量而没有 UV 分离&#xff0c;那么图像表示的就是黑白图像。彩色电视机采用的就是 YUV 图像&#xff0c;解决与和黑白电视机的兼容问题…

swift枚举(二)

swift枚举(一) No-payload enums 布局比较简单&#xff0c;也好理解&#xff0c;接下来看看 Single-payload enums Single-payload enums enum IFLEnum {case test_one(Bool)case test_twocase test_threecase test_four}print(MemoryLayout<IFLEnum>.size)print(Memor…

Vue事件处理器:事件绑定基础、事件修饰符:stop、prevent、capture、self、once;

先看代码&#xff1a; <body><div id"box">{{count}}<button click"handleAdd1()">add1</button><button click"handleAdd2">add2</button></div><script>new Vue({el: "#box",dat…

关于电脑使用的实用技巧

电脑几乎是我们每天都会用到的工具&#xff0c;那么电脑的使用技巧你知道多少呢&#xff1f;今天&#xff0c;我来为大家整理了几个常用的技巧&#xff0c;希望对大家的工作或学习效率有所帮助。 技巧一&#xff1a;快速查找文档按Windows E键打开电脑中的资源管理器&#xff0…

[附源码]SSM计算机毕业设计个性化新闻推荐系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

记一次神奇的 pipe 错误

文章目录1. 写在最前面2. 问题原因3. 解决问题3.1 CAP 的历史说明3.2 CAP 拆分的能力集合说明3.3 如何知道某个程序的能力集合3.3.1 查看只能写入 4096B 大小的程序能力位图3.3.2 查看能写入 65536B 大小的能力位图3.3.3 比较两个能力位图3.3.4 为 pod 增加 CAP_SYS_RESOURCE 的…

数字信号处理-4-三角函数合成与傅里叶级数

1 三角函数合成 函数正交&#xff08;数字信号处理-3-函数的正交&#xff09;&#xff0c;那它们相互之间无法通过组合得出对方的表达式&#xff0c;如&#xff1a;sinx 与 cosx 正交&#xff0c;acosnx 是无法表示 sinx 的。相互正交的各类三角函数是制作许多波形的基本单位。…

KT148A语音芯片按键版本一对一触发播放功能描述_V4

目录 一、简介 KT148A语音芯片--按键版本&#xff0c;支持3个IO口一对一触发 。同时也支持用户自己更换芯片内部的声音文件&#xff0c;方法&#xff0c;参考我们另外一份文档的描述“20220704_KT148A芯片自己更换声音的方法V3”。请留意&#xff0c;需要样品联系客服&#xf…

钡铼EdgeIO边缘计算 I/O 控制器

BL200 系列耦合器是一个数据采集和控制系统&#xff0c;基于强大的 32 位微处理器设计&#xff0c; 采用 Linux 操作系统&#xff0c;支持 Modbus&#xff0c;MQTT&#xff0c;OPC UA&#xff0c;Profinet&#xff0c;EtherCAT&#xff0c;Ethernet/IP&#xff0c; BACnet/IP…

程序员月薪8000,丢人吗?

近日&#xff0c;拉勾招聘数据研究院针对平台的程序员群体开展了深度调研&#xff0c;发布了《拉勾招聘2022程序员群体职场洞察报告》&#xff0c;呈现程序员最新的职场薪资水平。 *数据来源拉勾 从上图中可以看到&#xff0c;74%的00后应届毕业生的月薪在1-3万元区间&#…

C++语言的return语句的说明

C语言的return语句的说明 为了完成某一功能的程序指令&#xff08;语句&#xff09;的集合&#xff0c;称为函数。在程序中&#xff0c;编写函数的主要目的是将一个需要很多行代码的复杂问题分解为一系列简单的任务来解决&#xff0c;而且&#xff0c;同一个任务&#xff08;函…

Qt5开发从入门到精通——第十一篇三节(Qt5 事件处理及实例——事件过滤及实例)

提示&#xff1a;欢迎小伙伴的点评✨✨&#xff0c;相互学习c/c应用开发。&#x1f373;&#x1f373;&#x1f373; 博主&#x1f9d1;&#x1f9d1; 本着开源的精神交流Qt开发的经验、将持续更新续章&#xff0c;为社区贡献博主自身的开源精神&#x1f469;‍&#x1f680; 文…