Android Jetpack架构组件之Lifecycle入门

态度决定一切 细节决定成败

一、前言

——回顾了一下之前学习过的东西并打算把这些东西整理成文章,加深映像和理解,同时也传达自己的见解供大家参考,若存在错误或不足的地方,希望您能指出。
本篇主要介绍Lifecycle,根据下面结构图进行分析。

本篇结构图

LifeCycle相关链接——官方文档接口文档相关依赖文档

二、简介

(1)是什么

—— Lifecycle 是具有生命周期感知能力的组件。简单的理解当Activity/Fragment的生命周期产生变化时,lifeCycle组件也会有相应的生命周期变化。我们可以通过使用lifeCycle组件在自定义的类中管理Activity/fragment的生命周期。
主要由三大部分构成:Lifecycle、LifecycleOwner、LifecycleObserver

  • Lifecycle:是一个持有组件生命周期状态与事件(如Activity或Fragment)的信息的类
  • LifecycleOwner:Lifecycle的提供者,通过实现LifecycleOwner接口来访问Lifecycle(生命周期)对象。Fragment和FragmentActivity类实现了LifecycleOwner接口,它具有访问生命周期的getLifecycle方法。您还可以在自己的类中实现LifecycleOwner。
  • LifecycleObserver:Lifecycle观察者,实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

(2)有什么用

—— 常见的模式是在Activity和Fragment的生命周期方法中实现依赖组件的操作(取消注册/监听,释放内存...),如果不这样做可能会触发内存泄漏甚至应用程序崩溃。然而,这种模式会导致糟糕的代码组织和错误的扩散,。通过使用生命周期感知组件,您可以将依赖组件的代码移出生命周期方法,并移到组件本身

这里举个官方文档的例子说明一下,也更容易理解
常见的模式

class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) { /*...*/ }
    void start() { /*connect to system location service*/ }
    void stop() { /*disconnect from system location service*/ }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;
    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> { /* update UI */ });
    }
    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }
    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

实际的运用中,Activity的onStart()和onStop()方法中会有很多的调用来管理UI和其他组件,以响应生命周期的当前状态。管理多个组件会在生命周期方法中放置大量的代码,这使得它们很难维护。

Lifecycle模式

public class MyLocationListener implements LifecycleObserver {
    private static final String TAG = "MyLocationListener ";
    public MyLocationListener(Context context, Callback callback) { /*...*/ }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void start(){
        Log.e(TAG, "start: " );
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stop(){
        Log.e(TAG, "stop: " );
    }
}
//Activity/Fragment中使用
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLocationListener myLocationListener = new MyLocationListener(this, (location) -> { /* update UI */ });
    getLifecycle().addObserver(myLocationListener );
}

通过Lifecycle组件可以在各自的类中通过注释响应生命周期的当前状态。

(3)有什么优点

1.结构更加清晰,更容易管理生命周期
2.降低维护难度
3.降低耦合度

就是如此简单而又好用,那么具体如何使用请看下文分解。

三、基本使用

(4)怎么使用

  • 添加依赖

implementation 'androidx.appcompat:appcompat:1.1.0'

// 可选
dependencies {
    def lifecycle_version = "2.1.0"
    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}
  • 定义观察者
// 定义一个类实现LifecycleObserver接口,通过向其方法添加注释来监视组件的生命周期状态
public class MyObserver implements LifecycleObserver {
    private static final String TAG = "MyObserver";
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void start(){
        Log.e(TAG, "start: " );
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stop(){
        Log.e(TAG, "stop: " );
    }
}
  • 添加观察者
//通过调用生命周期类的addObserver()方法并传递观察者的实例来添加观察者。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyObserver myObserver = new MyObserver();
    getLifecycle().addObserver(myObserver);
}

这里提供入门级使用方式,下面举个例子

  • 案例
    ——广播的注册与取消注册处理

1.定义广播接收者

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("onReceive: action ",intent.getAction());
        Log.e("onReceive: content ",intent.getStringExtra("content"));
    }
}

2.定义lifecycle观察者

class BroadCastObserver implements LifecycleObserver {
    private static final String TAG = "BroadCastObserver";
    private Activity mActivity;
    private MyBroadcastReceiver mBroadcastReceiver;
    public BroadCastObserver(Activity activity) {
        this.mActivity = activity;
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void register(){
        Log.e(TAG, "register: " );
        mBroadcastReceiver = new MyBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("xxx");
        mActivity.registerReceiver(mBroadcastReceiver, intentFilter);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void unRegister(){
        Log.e(TAG, "unRegister: " );
        mActivity.unregisterReceiver(mBroadcastReceiver);
    }
}

3.添加观察者

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BroadCastObserver mBroadCastObserver = new BroadCastObserver(this);
        getLifecycle().addObserver(mBroadCastObserver);
    }

4.发送广播

    public void onClick(View v) {
        Intent intent = new Intent();
        intent.setAction("xxx");
        intent.putExtra("content", "广播1号");
        sendBroadcast(intent);
    }

输出结果

好了,使用方式就简单介绍到这里。大家有空也可以自己试试Service

四、原理

本来想写成一篇的,结果发现分析的源码有点多,只好拆开来。避免篇幅太长,看着累。。。
《Android Jetpack架构组件之Lifecycle源码分析》

五、总结

也不知道要写什么。就简单描述一下使用过程,lifecycle使用了观察者模式。
1.先声明了一个观察者,用来监听被观察者(Activity/Fragment)。
2.观察者通过实现LifecycleObserver接口,使用注解来监听被观察者发生的变化。
3.那么是如何监听的,这次就使用到了lifecycle。lifecycle相当于一个桥梁,把两者关联在一起。
4.被观察者通过实现LifecycleOwner接口先连接了桥梁。
5.观察者则通过getLifecycle().addObserver()方法也建立起连接。
通俗描述大概就是这么一回事,具体的实现方式还是要根据源码来分析。事实并没想的这么简单,源码也是挺多。

六、内容推荐

七、项目参考

Demo例子镶嵌到下面Demo中
Github ——apk下载体验地址
若您发现文章中存在错误或不足的地方,希望您能指出!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容