文章目录

  • 1.1 LifeCycle的诞生
  • 1.2 LifeCycIe的原理
  • 1.3 在Activity中使用
  • 1.4 使用LifecycleService解耦Service与组件
  • 1.5 使用ProcessLifecycleOwner监听应用程序的生命周期
    • ProcessLifecycIeOwner存在的意义
    • ProcessLifecycIeOwner的具体使用方法
  • 1.6 一些小Tips

1.1 LifeCycle的诞生

解耦是软件开发中永恒的话题。在Android应用程序开发中,解耦很大程度上表现为系统组件[1]的生命周期与普通组件[2]之间的解耦。普通组件在使用过程中通常需要依赖于系统组件的生命周期。有时候,我们不得不在系统组件的生命周期回调方法中,主动对普通组件进行调用或控制。因为普通组件无法主动获知系统组件的生命周期事件。

举个例子,我们经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,而在页面的onDestroy()方法中对组件进行资源回收工作。这样的工作非常烦琐,会让页面与组件之间的耦合度变高。但这些工作又不得不做,因为这可能会引发内存泄漏。

我们希望我们对自定义组件的管理,不依赖于页面生命周期的回调方法。同时,在页面生命周期发生变化时,也能够及时收到通知。这在组件化和架构设计中显得尤为重要,如图2-1所示。

为此,Google提供了LifeCycle作为解决方案。LifeCycle可以帮助开发者创建可感知生命周期的组件。这样,组件便能够在其内部管理自己的生命周期,从而降低模块间的耦合度,并降低内存泄漏发生的可能性。LifeCycle不只对Activity/Fragment有用,在Service和Application中也能大显身手。

1.2 LifeCycIe的原理


LifeCycle是如何解决这个问题的呢?Jetpack为我们提供了两个类:LifecycleOwner(被观察者)和LifecycleObserver(观察者)。即通过观察者模式,实现对页面生命周期的监听。

通过查看SupportActivity的源码,可以看到,在新版本的SDK包中,Activity已经默认实现了LifecycleOwner接口。LifecycleOwner接口中只有一个getLifecycle(LifecycleObserver observer)方法,LifecycleOwner正是通过该方法实现观察者模式的。源码示例如下。

从以上源码可知,SupportActivity已经替我们实现了被观察者应该实现的那一部分代码。因此,我们不需要再去实现这部分代码。当我们希望监听Activity的生命周期时,只需要实现观察者那一部分的代码,即让自定义组件实现LifecycleObserver接口即可。该接口没有接口方法,无须任何具体实现

除Activity之外,在新版本的SDK中,Fragment同样也默认实现了LifecycleOwner接口。因此,以上案例同样适用于Fragment。Fragment的源码如下所示。

1.3 在Activity中使用

示例如下:

public class MyLocationListener implements LifecycleObserver {public MyLocationListener(Context activity,OnLocationChangeListener changeListener) {}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)private void startGetLocation(){Log.i("MyLocationListener","OnResume");}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)private void stopGetLocation(){Log.i("MyLocationListener","OnPause");}public interface OnLocationChangeListener{void onChange(double latitude,double longitude);}
}

在Activity

public class MainActivity extends AppCompatActivity {private MyLocationListener myLocationListener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myLocationListener=new MyLocationListener(this, new MyLocationListener.OnLocationChangeListener() {@Overridepublic void onChange(double latitude, double longitude) {}});getLifecycle().addObserver(myLocationListener);}
}

就这么简单!LifeCycle完美解决了组件对页面生命周期的依赖问题,使组件能够自己管理其生命周期,而无须在页面中对其进行管理。这无疑大大降低了代码的耦合度,提高了组件的复用程度,也杜绝了由于对页面生命周期管理的疏忽而引发的内存泄漏问题,这在项目工程量大的情况下是非常有帮助的。

1.4 使用LifecycleService解耦Service与组件

在上文中,我们介绍了如何利用LifeCycle来监听页面的生命周期,以达到解耦组件的目的。我们知道,拥有生命周期概念的组件除了Activity和Fragment,还有一个非常重要的组件是Service。为了便于对Service生命周期的监听,达到解耦Service与组件的目的,Android提供了一个名为LifecycleService的类。该类继承自Service,并实现了LifecycleOwner接口。与Activity/Fragment类似,它也提供了一个名为getLifecycle()的方法供我们使用。LifecycleService的源码如下所示

首先在build.gradle文件中加入

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

创建一个名为MyService的类,并让它继承自LifecycleService。由于LifecycleService是Service的直接子类,所以使用起来与普通Service没有差别。

import androidx.lifecycle.LifecycleService;public class MyService extends LifecycleService {private MyLifecycleObserver myLifecycleObserver;public MyService() {myLifecycleObserver = new MyLifecycleObserver();getLifecycle().addObserver(myLifecycleObserver);}
}
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;public class MyLifecycleObserver implements LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)private void startGetLocation(){Log.i("MyLocationListener","OnResume");}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)private void stopGetLocation(){Log.i("MyLocationListener","OnPause");}
}

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

ProcessLifecycIeOwner存在的意义

具有生命周期的系统组件除Activity、Fragment、Service外,还有Application。很多时候,我们会遇到这样的需求:我们想知道应用程序当前处在前台还是后台,或者当应用程序从后台回到前台时,我们能够得到通知。有不少方案能够实现该需求,但都不够好。在此之前,Google并没有为该需求提供官方解决方案,直到LifeCycle的出现。LifeCycle提供了一个名为ProcessLifecycleOwner的类,以方便我们知道整个应用程序的生命周期情况。

ProcessLifecycIeOwner的具体使用方法

首先,我们需要在app的build.gradle文件中添加相关依赖。

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
import com.example.jetpackdemo.LifeCycle.ApplicationObserver;
import com.example.jetpackdemo.LifeCycle.MyLifecycleObserver;public class MyApplication extends Application  {@Overridepublic void onCreate() {super.onCreate();ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationObserver());}
}
import android.util.Log;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;public class ApplicationObserver implements LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)private void onCreate(){Log.i("Application","OnCreate");}@OnLifecycleEvent(Lifecycle.Event.ON_START)private void onStart(){Log.i("Application","OnStart");}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)private void onResume(){Log.i("Application","OnResume");}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)private void onPause(){Log.i("Application","OnPause");}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)private void onStop(){Log.i("Application","OnStop");}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)private void onDestroy(){Log.i("Application","OnPause");}
}

通过以上示例可以看出,有了ProcessLifecycleOwner,我们可以轻而易举地获知应用程序何时退到后台,何时进入前台,进而执行一些业务操作。它使用起来非常简单,并且不会给项目增加任何的耦合度,但有以下几点需要注意。

  • ProcessLifecycleOwner是针对整个应用程序的监听,与Activity数量无关,你有一个Activity或多个Activity,对ProcessLifecycleOwner来说是没有区别的。
  • Lifecycle.Event.ON_CREATE只会被调用一次,而Lifecycle.Event.ON_DESTROY永远不会被调用。
  • 当应用程序从后台回到前台,或者应用程序被首次打开时,会依次调用Lifecycle.Event.ON_START和Lifecycle.Event.ON_RESUME。
  • 当应用程序从前台退到后台(用户按下Home键或任务菜单键),会依次调用Lifecycle.Event.ON_PAUSE和Lifecycle.Event.ON_STOP。需要注意的是,这两个方法的调用会有一定的延后。这是因为系统需要为“屏幕旋转,由于配置发生变化而导致Activity重新创建”的情况预留一些时间。也就是说,系统需要保证当设备出现这种情况时,这两个事件不会被调用。因为当旋转屏幕时,你的应用程序并没有退到后台,它只是进入了横/竖屏模式而已。

1.6 一些小Tips

1、尝试复用LifecycleRegistry
首先,LifecycleRegistry 本身就是一个成熟的 Lifecycle 实现类,它被实例化在Activity和Fragment中使用,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,完全可以直接在自定义LifecycleOwner中new一个LifecycleRegistry成员并返回它(简而言之就是:直接拿来用即可)。

以下是Google官方文档:

LifecycleRegistry:
An implementation of Lifecycle that can handle multiple observers.
It is used by Fragments and Support Library Activities.
You can also directly use it if you have a custom LifecycleOwner.

2、注解和DefaultLifecycleObserver的取舍
其次,Google的Lifecycle库中提供了一个 DefaultLifecycleObserver 类,方便我们直接实现LifecycleObserver接口,相比较于文中demo所使用的注解方式,Google官方更推荐我们使用 DefaultLifecycleObserver 类,并声明

一旦Java 8成为Android的主流,注释将被弃用,所以介于DefaultLifecycleObserver和注解两者之间,更推荐使用 DefaultLifecycleObserver 。

Android LifeCycle详解相关推荐

  1. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  2. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  3. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  4. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

  5. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  6. android WebView详解,常见漏洞详解和安全源码(上)

    这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.  由于博客内容长度,这次将分为上下两篇,上篇详解 WebView ...

  7. android子视图无菜单,Android 菜单详解

    Android中菜单分为三种,选项菜单(OptionMenu),上下文菜单(ContextMenu),子菜单(SubMenu) 选项菜单 可以通过两种办法增加选项菜单,一是在menu.xml中添加,该 ...

  8. Android StateFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121913352 本文出自[赵彦军的博客] 文章目录 系列文章 一.冷流还是热流 S ...

  9. Android SharedFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121911675 本文出自[赵彦军的博客] 文章目录 系列文章 什么是SharedF ...

最新文章

  1. 玩纸牌游戏计算机教案,小班数学好玩的扑克牌教案
  2. 孙庆新:做产品,感觉从何而来
  3. const那些事-初始化
  4. Git:改变世界的一次代码提交
  5. linux下配置钉钉内网穿透_4G工业路由器内嵌花生壳PHTunnel,为工业物联网提供智能内网穿透...
  6. [转]WF事件驱动(4) -持久化
  7. cognos transformer 建一个85w数据的cube所用的时间,接优化
  8. 计算机系毕业论文绪论,本科毕业论文绪论范文
  9. Python路飞学城老男孩内部书籍,Python全栈开发实战pdf
  10. STM32F103C8T6红外遥控解码
  11. 2016最新php授权验证系统v2.1,2016PHP受权验证系统V2.1完整版,域名+IP双重验证 一键升级受权系统 完美无错...
  12. Java面试题笔试题汇总
  13. WPS使用宏操作——减少重复性操作,提高效率
  14. 何小黑的2019年秋招面经~
  15. 面试,这些问题一定要问清楚!
  16. 层次分析法(AHP)基础概念整理+步骤总结
  17. 【论文阅读】PGM-index
  18. 插板法、捆绑法、插空法
  19. SpringBoot的easyui实现导入和导出功能到excel
  20. linux中搜索文件内容关键字--转载哈

热门文章

  1. 谈点Android系统的趋势
  2. 不小心删了自己的注册表怎么办
  3. Struts2介绍(一个大的工具库)
  4. 牛人经验:看美剧学习英语的诀窍
  5. 蓝桥杯嵌入式(G4系列):RTC时钟
  6. 智和网管平台SugarNMS电力行业综合网管解决方案
  7. 45个有用的JavaScript技巧,窍门和最佳实践
  8. 【产品体验】明星衣橱
  9. psv连接电脑显示无法连接服务器,psv ftp服务器找不到
  10. 国内网络安全公司、社区简介