【Android】Jetpack组件之LifeCycle

news2024/11/19 3:37:05

引言

Lifecycle组件是Android Jetpack架构组件之一,它提供了一种方法来管理Android组件(如Activity、Fragment和服务)的生命周期。Lifecycle组件帮助你执行与生命周期相关联的操作,确保在适当的时间发生适当的事情,例如,当你的应用进入后台时停止数据刷新,或者在应用回到前台时更新UI。

使用Lifecycle解耦页面与组件

Lifecycle 组件提供了一种方法来处理 Android 组件(如 Activity 和 Fragment)的生命周期。在 MVVM 架构中,Lifecycle 组件可以帮助 ViewModel 感知宿主的生命周期状态,从而在适当的时机进行数据加载或资源清理。

介绍一个控件:Chronometer是 Android 提供的一个用于显示计时器的 UI 控件。它继承自 View 类,专门用于展示和跟踪时间的流逝。Chronometer 控件不仅可以显示经过的时间,还可以在时间变化时提供格式化的文本显示,并且可以响应用户的开始、暂停和重置等操作

我们就使用这个控件来体验Lifecycle的作用,在活动当中放置一个Chronometer控件用来计算我们使用这个程序多长时间,按照之前所学的我们会在活动的回调函数当中写代码

public class MainActivity extends AppCompatActivity {
    Chronometer chronometer;
    long l;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
        chronometer = findViewById(R.id.chronometer);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //SystemClock.elapsedRealtime() 返回自开机以来经过的时间(以毫秒为单位),l 是之前保存的时间差值。
        //通过减去 l,计时器的基准时间被设置为上次暂停时的时间。
        chronometer.setBase(SystemClock.elapsedRealtime() - l);
        chronometer.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //后台运行计算并保存当前的时间差值。chronometer.getBase() 返回计时器的基准时间,通过计算当前时间减去基准时间,
        //可以得到从基准时间到当前时间经过的毫秒数,这个值被保存在 l 中,以便在下次 onResume() 时使用。
        l = SystemClock.elapsedRealtime() - chronometer.getBase();
        chronometer.stop();
    }
}
  • chronometer.setBase(SystemClock.elapsedRealtime() - l); 设置计时器的基底时间。这里 l 是之前保存的时间差,这样做是为了在 Activity 从 onPause 回来时,计时器能够从上次暂停的地方继续计时
  • l = SystemClock.elapsedRealtime() - chronometer.getBase(); 计算当前时间与计时器基底时间的差值,并将其保存在 l 中。这个值将在下次 onResume 时使用,以确保计时器的连续性

如何进行解耦呢?接下来就看看吧

public class MyChronomter extends Chronometer implements LifecycleObserver {
    private long l;
    public MyChronomter(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private void startMeter() {
        setBase(SystemClock.elapsedRealtime() - l);
        start();
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private void stopMeter() {
        l = SystemClock.elapsedRealtime() - getBase();
        stop();
    }
}

我们新创建了一个组件实现LifecycleObserver

LifecycleObserver 是 Android Architecture Components 中 Lifecycle 组件的一部分。它是一个接口,用于定义一个观察者,它可以观察到 LifecycleOwner 生命周期的变化

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 标记,这意味着当关联的 LifecycleOwner 从暂停状态恢复到前台(即 ON_RESUME 事件)时,这个方法会被调用,使用注解来明确调用的时间

代码不难理解,接下来我们就可以把主活动里面的多于代码删除了,但要为组件设置监听

getLifecycle().addObserver(chronometer); //给他设置监听

接下来运行程序就仍然实现了之前的记录下应用的使用时间,大大减少了活动里面代码的数量。

使用LifecycleService解耦Service组件

LifecycleService 是一个非常有用的组件,它允许你将后台服务(Service)与组件的生命周期解耦。这样,服务可以在不需要与特定活动(Activity)或片段(Fragment)紧密绑定的情况下运行

我们需要先导入依赖:

在这里插入图片描述

也可以直接使用快捷键F4

在这里插入图片描述

对你所要导入的依赖进行搜索与选择

在这里插入图片描述

点击OK就导入成功了!

接下开看看如何使用吧

  1. 创建 LifecycleService 子类:首先,你需要创建一个继承自 LifecycleService 的类。这将是你的服务类,你可以在这里定义服务的行为。
public class MyLocationService extends LifecycleService {
    public MyLocationService() {
        Log.d("hhhhhh","MyLocationService");
        MyLocationObserver observer = new MyLocationObserver(this);
        getLifecycle().addObserver(observer);
    }
}

我们定义了一个服务,并为其设置监听

  1. 注册 LifecycleObserver:在你的 LifecycleService 子类中,你需要注册一个或多个 LifecycleObserver。这些观察者将监听生命周期事件,并在事件发生时执行相应的操作。
  2. 处理生命周期事件:在 LifecycleObserver 中,你可以使用 @OnLifecycleEvent 注解来标记方法,这些方法将在特定的生命周期事件发生时被调用。
public class MyLocationObserver implements LifecycleObserver {
    private Context context;
    private LocationManager locationManager;
    private MyLocationListener listener;

    public MyLocationObserver(Context context) {
        this.context = context;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private void startGetLocation() {
        Log.d("hhhhhh","startGetLocation");
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        listener = new MyLocationListener();
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        locationManager.requestLocationUpdates
                (LocationManager.GPS_PROVIDER, 300,
                        1, listener);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private void stopGetLocation() {
        Log.d("hhhhhh","stopGetLocation");
        locationManager.removeUpdates(listener);
    }
    static class MyLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(@NonNull Location location) {
            Log.d("hhhhhh","LocationChanged" + location.toString());
        }
    }
}

上面的注解就无需再做过多的解释了,在上面解耦页面的时候就已经介绍过了,对部分不熟悉的代码进行简单介绍吧:

  • locationManager.requestLocationUpdates:这个方法请求位置更新,指定使用 GPS_PROVIDER,设置更新的时间间隔为 300 毫秒,水平精度为 1 米,并将 listener 作为回调。
  • locationManager.removeUpdates(listener):当不再需要位置更新时,这个方法将停止位置更新,以避免不必要的资源消耗和电池使用。
  1. 在清单文件中注册服务:最后,你需要在Android项目的清单文件(AndroidManifest.xml)中注册你的 LifecycleService
<service
            android:name=".MyLocationService"
            android:enabled="true"
            android:exported="true"></service>

接下来运行程序,当我们按下开始按钮再按下结束按钮,此时观察打印日志:

在这里插入图片描述

使用ProcessLifecycleOwner监听应用程序生命周期

我们先来看看如何使用吧

  1. 创建 LifecycleObserver
public class MyApplicationObserve implements LifecycleObserver {
    private static String TAG = "hhhhhh";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private void onCreate() {
        Log.d(TAG, "onCreate");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onStart() {
        Log.d(TAG, "onStart");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private void onResume() {
        Log.d(TAG, "onResume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private void onPause() {
        Log.d(TAG, "onPause");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onStop() {
        Log.d(TAG, "onStop");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private void onDestroy() {
        Log.d(TAG, "onDestroy");
    }
}
  1. 注册 LifecycleObserver
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle()
                .addObserver(new MyApplicationObserve());
    }
}
  • ProcessLifecycleOwner.get().getLifecycle() 通过 ProcessLifecycleOwner 的单例实例获取整个应用程序进程的 Lifecycle 对象。
  • addObserver(new MyApplicationObserve())Lifecycle 对象添加一个新的观察者 MyApplicationObserve。当应用程序的生命周期发生变化时,这个观察者将收到通

<application android:name=".MyApplication"> 这行代码位于 AndroidManifest.xml 文件中,它指定了 MyApplication 作为应用程序的入口类

使用 ProcessLifecycleOwner 时需要注意以下几点:

  • ON_CREATE 事件只会被分发一次,即应用程序启动时。
  • ON_DESTROY 事件永远不会被分发,因为进程的生命周期直到进程被系统终止才会结束。
  • ON_START, ON_RESUME, ON_PAUSE, ON_STOP 事件会随着活动的生命周期变化而分发,但可能会有延迟,因为系统要确保不会因为活动的配置更改(如屏幕旋转)而重复发送这些事件。

接下来运行程序,我们推到后台一次,再进去最后停止运行程序:

在这里插入图片描述

文章到这里就结束了!

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

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

相关文章

服务器几核几G几M是什么意思?如何选择?

服务器几核几G几M是什么意思&#xff1f;我们建站、搭建网络平台都要用到云服务器&#xff0c;不管在腾讯云、阿里云还是别的云服务平台选购&#xff0c;都会接触到服务器配置。云服务器就是把物理服务器&#xff08;俗称“母鸡”&#xff09;&#xff0c;用虚拟机技术虚拟出多…

LeetCode: 1971. 寻找图中是否存在路径

寻找图中是否存在路径 原题 有一个具有 n 个顶点的 双向 图&#xff0c;其中每个顶点标记从 0 到 n - 1&#xff08;包含 0 和 n - 1&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点…

mips指令系统简介

**MIPS&#xff08;Microprocessor without Interlocked Piped Stages&#xff09;**&#xff1a;这是一种RISC&#xff08;精简指令集计算&#xff09;芯片架构&#xff0c;由John L. Hennessy设计&#xff0c;特点是没有内部互锁的流水级&#xff0c;简化了处理器设计。 对比…

python Scrapy 框架断点设置

文章目录 前言python Scrapy 框架断点设置1. 常用的 pdb 调试命令2. 示例流程 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖…

等保2.0数据库测评之优炫数据库测评

一、优炫数据库介绍 优炫数据库系统主要包含&#xff1a;优炫数据库&#xff08;以下简称UXDB&#xff09;、优炫数据库管理平台&#xff08;以下简称 UXDBWeb&#xff09;和优炫数据库图形化开发软件&#xff08;以下简称UXDBAdmin&#xff09;。UXDB是一款数据库软件&#x…

求恰好为k 的区间数量(滑动窗口进阶版)

前言&#xff1a;之前做的滑动窗口都是可以直接一遍过&#xff0c;然后每次右边确定了以后&#xff0c;左边不断缩小寻找最优解 但是这个题目呢我们不仅要保证我们的辅音字母的个数恰好为k&#xff0c;其他元音字母的个数只要每个都出现了就行&#xff0c;这个就导致我们不能用…

解析时间字符串为毫秒

Java 8中现已包含持续时间解析为纳秒再转换成毫秒 PeriodFormatter formatter new PeriodFormatterBuilder().appendDays().appendSuffix("d ").appendHours().appendSuffix("h ").appendMinutes().appendSuffix("min").toFormatter();Period p…

7. 机器人项目

在 “项目 ”章节中&#xff0c;我会暂时停止向你灌输新的理论&#xff0c;而是让我们一起完成一个程序。学习编程&#xff0c;理论是必要的&#xff0c;但阅读和理解实际程序同样重要。 本章的课题是建立一个自动机&#xff0c;一个在虚拟世界中执行任务的小程序。我们的自动机…

plt.bar函数介绍及实战

目录 plt.bar() 函数实战 plt.bar() 函数 plt.bar() 函数是 Matplotlib 中用于创建柱状图的函数。它用于在图形中绘制一个或多个柱状图&#xff0c;通常用于展示类别型数据的数量或大小的比较。 基本语法&#xff1a; plt.bar(x, height, width0.8, bottomNone, aligncenter…

【css】常见布局概述

本文将对css的常见布局方案进行概述&#xff0c;给大家提供系统化的布局解决方案参考。 一、流式布局 二、浮动布局 三、定位布局 四、弹性布局 五、网格布局 一、流式布局 顾名思义&#xff0c;该布局基于dom的文档流进行布局&#xff0c;是最常用、最原始的布局方式。 …

ThinkPHP发送邮件教程:从配置到发送指南!

ThinkPHP发送邮件功能实现策略&#xff1f;Thinkphp如何发邮件&#xff1f; ThinkPHP作为一个流行的PHP框架&#xff0c;提供了强大的邮件发送功能&#xff0c;使得开发者可以轻松地在应用中集成邮件发送功能。AokSend将详细介绍如何在ThinkPHP中配置和发送邮件。 ThinkPHP发…

Goland 设置GOROOT报错 The selected directory is not a valid home for Go SDK

问题描述 将go版本从1.16升级到1.22时配置GoRoot报错了如下图问题 The selected directory is not a valid home for Go SDK起因的是我的这个goland比较老了&#xff0c;2020年的。所以需要设置下版本 解决 OK&#xff0c;说一下解决办法&#xff1a; 找到go的安装路径&am…

Tomcat架构解析

Tomcat: 是基于JAVA语言的轻量级应用服务器&#xff0c;是一款完全开源免费的Servlet服务器实现。 1. 总体设计 socket: 其实就是操作系统提供给程序员操作“网络协议栈”的接口&#xff0c;你能通过socket的接口&#xff0c;来控制协议&#xff0c;实现网络通信&#xff0c;达…

.Net 6.0 监听Windows网络状态切换

上次发了一个文章获取windows网络状态&#xff0c;判断是否可以访问互联网。传送门&#xff1a;获取本机网络状态 这次我们监听网络状态切换&#xff0c;具体代码如下&#xff1a; public class WindowsNetworkHelper {private static Action<bool>? _NetworkStatusCh…

《Programming from the Ground Up》阅读笔记:p117-p146

《Programming from the Ground Up》学习第8天&#xff0c;p117-p146总结&#xff0c;总计30页。 一、技术总结 1.共享函数用法示例 (1)不使用共享函数 linux.s&#xff1a; # filename:linux.s# system call numbers(按数字大小排列&#xff0c;方便查看) .equ SYS_READ,…

FreeRTOS学习笔记一——FreeRTOS介绍

RTOS学习笔记&#xff0c;主要参考正点原子教程 目录 FreeRTOS特点任务调度方式抢占式调度时间片调度 任务状态状态转换任务列表 FreeRTOS特点 实现多个任务功能划分延时函数实现任务调度高优先级抢占低优先级每个任务都有自己的栈空间 注意&#xff1a; 中断可以打断任意任务…

Spring依赖注入推荐使用构造函数注入而非@Autowired

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl在Spring框架中,依赖注入(Dependency Injection, DI)是实现组件之间松耦合的关键技术。Spring支持多种依赖注入方式,其中构造函数注入和基于@Autowired注解的注入是两种常见的方法。然而,Spri…

活体检测标签之2.4G有源RFID--SI24R2F+

首先从客户对食品安全和可追溯性的关注切入&#xff0c;引出活体标签这个解决方案。接着分别阐述活体标签在动物养殖和植物产品方面的应用&#xff0c;强调其像 “身份证” 一样记录重要信息&#xff0c;让客户能够了解食品的来源和成长历程&#xff0c;从而放心食用。最后呼吁…

手机USB连接不显示内部设备,设备管理器显示“MTP”感叹号,解决方案

进入小米驱动下载界面&#xff0c;等小米驱动下载完成后&#xff0c;解压此驱动文件压缩包。 5、小米USB驱动安装方法&#xff1a;右击“计算机”&#xff0c;从弹出的右键菜单中选择“管理”项进入。 6、在打开的“计算机管理”界面中&#xff0c;展开“设备管理器”项&…

VS开发 - 静态编译和动态编译的基础实践与混用

目录 1. 基础概念 2. 直观感受一下静态编译和动态编译的体积与依赖项目 3. VS运行时库包含哪些主要文件&#xff08;从VS2015起&#xff09; 4. 动态库和静态库混用的情况 5. 感谢清单 1. 基础概念 所谓的运行时库&#xff08;Runtime Library&#xff09;就是WINDOWS系统…