【Jetpack】Lifecycle 架构组件 ( 系统组件与普通组件解耦 | Lifecycle 解耦系统组件与普通组件 | 解耦服务组件与普通组件 | 监听应用程序生命周期 )

文章目录

  • 一、系统组件与普通组件解耦
  • 二、Lifecycle 解耦 Activity 系统组件与 UI 组件
    • 1、传统实现方式
      • ① Activity 系统组件
      • ② 布局文件
      • ③ 执行效果
    • 2、LifeCycle 实现方式
      • ① 自定义 UI 组件
      • ② Activity 系统组件
      • ③ 布局组件
      • ④ 执行效果
  • 三、LifecycleService 解耦 Service 与 UI 组件
    • 1、构建脚本导入依赖
    • 2、Android Studio 中搜索并添加依赖
    • 3、布局文件属性排序
    • 4、代码实现
      • ① LifecycleService 组件
      • ② LifecycleObserver 业务逻辑
      • ③ AndroidManifest.xml 清单文件
      • ④ Activity 系统组件
      • ⑤ Activity 组件对应的布局文件
      • ⑥ 执行结果
  • 四、ProcessLifecycleOwner 监听整个应用程序的 Activity 生命周期
    • 1、ProcessLifecycleOwner 说明
    • 2、代码实现
      • ① LifecycleObserver 组件
      • ② 自定义 Application
      • ③ AndroidManifest.xml 清单文件配置
      • ④ 执行效果





一、系统组件与普通组件解耦



在 Android 应用开发过程中 , 普通组件 如 UI 控件 , 需要 与 Android 组件生命周期函数相关联 , 当 Android 组件生命周期 发生改变时 , 可以 通知 普通组件 执行某种操作 ;

如 : 显示的自定义 UI 组件 , 要随着 Activity 组件生命周期的变化 , 进行相应改变 , 当 界面被覆盖 也就是 onPause 时 执行某种改变 , 当界面进入后台 onStop 时 , 执行某种改变 ;


Android 应用系统架构 中 , 总是希望 Android 组件 越小越好 , 不要把 Activity , Service 等组件写的很大 , 将 系统组件 实际的业务逻辑组件 进行分离 ;

上述操作 , 就是将 系统组件普通组件 进行 解耦 , 降低代码复杂度 , 提高程序的可读性 , 可维护性 ;

Lifecycle 架构组件 就是实现上述 解耦功能 ;


Lifecycle 的适用场景 :

  • 建立 可感知 系统组件 生命周期 自定义 UI 组件 , 如 创建 自定义组件 , 可以直接在组件内部处理 Activity 生命周期的 回调 , 不需要在 Activity 组件中开发大量的 自定义组件 相关的业务逻辑 ;
  • 使用了 Lifecycle 的 组件 , 组件可移植性增强 , 在组件内部 增加了 对 系统组件 生命周期的处理 , 该组件可以任意移植 , 不需要在 Activity 中开发额外的代码 ;

支持 Lifecycle 架构组件 的 Android 系统组件 :

  • Activity
  • Fragment
  • Service
  • Application




二、Lifecycle 解耦 Activity 系统组件与 UI 组件



在上一个章节 , 讲到 将 系统组件普通组件 进行 解耦 , Activity 组件就是 系统组件 , 在 Activity 中使用到的 UI 组件 , 就是实际实现业务逻辑的 普通组件 ;

实现一个功能 : 监控页面的打开时间 , 将页面打开时间直接显示在页面中 ;


1、传统实现方式


使用传统方式 , UI 组件 直接定义在了 Activity 系统组件 中 , 二者耦合性太高 , 不利于项目维护 ;

UI 组件的业务逻辑 与 Activity 系统组件 绑定程度很高 , 并且 UI 组件的逻辑 与 Activity 生命周期关联程度很高 ;


① Activity 系统组件

package kim.hsl.lifecycle

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Chronometer

class MainActivity : AppCompatActivity() {

    /**
     * UI 组件的业务逻辑 与 Activity 系统组件 绑定程度很高
     * 并且 UI 组件的逻辑 与 Activity 生命周期关联程度很高
     */
    lateinit var chronometer: Chronometer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        chronometer = findViewById(R.id.chronometer)
    }

    override fun onResume() {
        super.onResume()
        chronometer.start()
    }

    override fun onPause() {
        super.onPause()
        chronometer.stop()
    }
}

② 布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Chronometer
        android:id="@+id/chronometer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

③ 执行效果

在这里插入图片描述


2、LifeCycle 实现方式


自定义 UI 组件实现 LifeCycleObserver 接口 , 再将 该 自定义组件Activity 组件 绑定 , 那么 Activity 的生命周期函数回调时 , 会 自动触发回调 LifeCycleObserver 接口函数 ;

这种实现方式 , 解耦 UI 组件Android 系统组件 ;


① 自定义 UI 组件

在下面的自定义组件中 , 实现了 LifecycleObserver 接口 , 在 Activity 中 , 调用 LifeCycle#addObserver 函数 , 为该 自定义组件添加 生命周期回调 ;

package kim.hsl.lifecycle

import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.widget.Chronometer
import androidx.annotation.RequiresApi
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MyChronometer: Chronometer, LifecycleObserver {

    constructor(context: Context?): super(context)
    constructor(context: Context?, attrs: AttributeSet?): super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int):
            super(context, attrs, defStyleAttr)
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int):
            super(context, attrs, defStyleAttr, defStyleRes)

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun startMeter() {
        // 开始计时
        this.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun stopMeter() {
        // 停止计时
        this.stop()
    }
}

② Activity 系统组件

在 Activity 中 , 先通过 getLifecycle() 函数 获取 LifeCycle 实例 , 然后调用 Lifecycle#addObserver 函数 , 为 自定义 UI 组件 添加 生命周期回调 ;

package kim.hsl.lifecycle

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    lateinit var chronometer: MyChronometer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        chronometer = findViewById(R.id.chronometer)
        // 为自定义组件 MyChronometer 添加 Activity 生命周期回调方法
        lifecycle.addObserver(chronometer)
    }
}

③ 布局组件

布局中使用的是 实现了 LifeCycleObserver 接口的 自定义 UI 组件 ;

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <kim.hsl.lifecycle.MyChronometer
        android:id="@+id/chronometer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

④ 执行效果

在这里插入图片描述





三、LifecycleService 解耦 Service 与 UI 组件




1、构建脚本导入依赖


要使用 Lifecycle , 需要导入 androidx.lifecycle:lifecycle-extensions:2.2.0 依赖库 , 在 build.gradle 构建脚本 中 , 导入依赖 ;

dependencies {
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}

2、Android Studio 中搜索并添加依赖


如果 不知道依赖库的具体路径 , 可以使用 Android Studio 的依赖库搜索功能 ;


搜索并添加依赖步骤 :

右键点击工程根目录 , 在弹出的菜单中选择 " Open Module Settings " 选项 , 或者直接使用 F4 快捷键 ,

在这里插入图片描述

在弹出的 " Project Structure " 对话框中 , 左侧选择 " Dependencies " 面板 , 点击右侧的 " Add Dependency " 按钮 ,

在这里插入图片描述

在中间的 Modules 面板中 , 选择要添加依赖的 Module , 然后右侧选择 添加 " Library Dependency " 选项 ,

在这里插入图片描述

在弹出的 " Add Library Dependency " 对话框中 , 搜索 " androidx.lifecycle " , 找到要导入的依赖库 , 选择依赖库版本 , 即可导入该依赖库 ;

在这里插入图片描述
选择完毕后 , 点击 应用按钮 ,
在这里插入图片描述

build.gradle 构建脚本 中 , 会自动插入该依赖 ;

dependencies {
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}

在这里插入图片描述


3、布局文件属性排序


写完 布局文件后 , 可以选择 " 菜单栏 | Code | Rearrange Code " , 可以对布局文件中的 组件 属性进行排序 , 一般会按照 ID , 布局宽高属性 , 布局内容属性 , 布局的位置属性 进行排序 , 提高代码的可读性 ;
在这里插入图片描述


4、代码实现


① LifecycleService 组件


LifecycleService 组件Service 组件类 的子类 , 一般使用 自定义类继承 LifecycleService 类 ;

自定义 LifecycleService 类中 , 需要创建 LifeCycleObserver 实例对象 , 该对象中定义了实际的业务逻辑 ;


传统 代码行为 , 一般 直接在 Service 系统组件中 直接 定义 普通的业务逻辑组件 , 导致 系统组件 与 普通组件 耦合性很高 ;

引入了 LifeCycle 架构组件 后 , LifecycleService 组件 LifeCycleObserver 绑定 , LifeCycleObserver 实例对象 就对应了 普通的业务逻辑组件 , 在 该对象中 有对应的 Service 生命周期回调 ;

这就实现了 系统组件 与 普通组件 的解耦 ;


代码示例 :

package kim.hsl.lifecycle

import android.util.Log
import androidx.lifecycle.LifecycleService

/**
 * Android 系统组件
 */
class MyLifecycleService: LifecycleService {
    constructor(){
        Log.i("LifeCycleDemo", "MyService Init")

        // 为 Service 添加 生命周期回调
        // 解耦 Service 系统组件 与 普通逻辑组件
        var myLifeCycleObserver = MyLifeCycleObserver()
        lifecycle.addObserver(myLifeCycleObserver)
    }
}

② LifecycleObserver 业务逻辑


LifecycleObserver 中定义了实际的业务逻辑 , 对应着 普通组件 , 在 LifecycleService 中 , 没有业务相关代码 , 借此实现了 系统组件 与 普通组件 的 解耦 操作 ;

在函数上添加

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)

注解 , 在 LifecycleService 中执行 onCreate 生命周期函数时 , 就会回调该方法 ;

在函数上添加

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)

注解 , 在 LifecycleService 中执行 onDestroy 生命周期函数时 , 就会回调该函数 ;


LifecycleObserver 业务逻辑代码 :

package kim.hsl.lifecycle

import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MyLifeCycleObserver: LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun serviceStart(){
        // 服务启动
        Log.i("LifeCycleDemo", "MyService ON_CREATE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun serviceStop(){
        // 服务停止
        Log.i("LifeCycleDemo", "MyService ON_DESTROY")
    }
}

③ AndroidManifest.xml 清单文件


主要是 在 清单文件中配置 自定义的 LifecycleService 类 ;

<service android:name="kim.hsl.lifecycle.MyLifecycleService" />

清单文件配置 :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LifeCycleDemo"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>

        <service android:name="kim.hsl.lifecycle.MyLifecycleService" />
    </application>

</manifest>

④ Activity 系统组件


在 Activity 系统组件中 , 主要实现 自定义的 LifecycleService 的启动和停止操作 ;

启动服务 :

startService(Intent(this, MyLifecycleService::class.java))

停止服务 :

stopService(Intent(this, MyLifecycleService::class.java))

Activity 系统组件代码 :

package kim.hsl.lifecycle

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun startLifeCycleService(view: View) {
        startService(Intent(this, MyLifecycleService::class.java))
    }
    fun stopLifeCycleService(view: View) {
        stopService(Intent(this, MyLifecycleService::class.java))
    }
}

⑤ Activity 组件对应的布局文件


在该布局文件中 , 主要设置两个按钮 , 分别用于 启动服务停止服务 ;


布局文件源码 :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="启动服务"
        android:onClick="startLifeCycleService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.283"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.086" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服务"
        android:onClick="stopLifeCycleService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.709"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.086" />

</androidx.constraintlayout.widget.ConstraintLayout>

⑥ 执行结果


执行后 , 先点击 " 启动服务 " 按钮 , 然后点击 " 停止服务 " 按钮 ;
在这里插入图片描述

点击 启动服务 按钮后 , 输出日志 :

2023-03-03 15:23:01.305 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService Init
2023-03-03 15:23:01.309 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService ON_CREATE

点击 停止服务 按钮后 , 输出日志 :

2023-03-03 15:23:03.607 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService ON_DESTROY

完整日志输出 :

2023-03-03 15:23:01.305 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService Init
2023-03-03 15:23:01.309 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService ON_CREATE
2023-03-03 15:23:03.607 31578-31578/kim.hsl.lifecycle I/LifeCycleDemo: MyService ON_DESTROY

在这里插入图片描述





四、ProcessLifecycleOwner 监听整个应用程序的 Activity 生命周期




1、ProcessLifecycleOwner 说明


在 Android 应用的 Application 中 , 使用 ProcessLifeCycleOwner 可以监听 应用程序 的 生命周期 ;

ProcessLifeCycleOwner 监听的是 整个 Android 应用程序 的 Activity 生命周期 , 该监听与 Activity 数量无关 ;

在 LifecycleObserver 中 , Lifecycle.Event.ON_CREATE 注解修饰的 函数 只会被 调用一次 , 只要有一个 Activity 存在 , 就不会触发 Lifecycle.Event.ON_DESTROY , 所有的 Activity 都退出 , 就意味着 应用 退出 , 进程直接消亡 , 因此 Lifecycle.Event.ON_DESTROY 注解修饰的函数 永远都 不会被触发 ;


2、代码实现


① LifecycleObserver 组件


自定义 LifecycleObserver 组件 , 用于监听 整个应用的 Activity , 当 Activity 调用对应生命周期函数时 , 会自动回调该组件内的相应回调 ;


代码示例 :

package kim.hsl.lifecycle

import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MyLifeCycleObserver: LifecycleObserver {
    val TAG = "LifecycleDemo"

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        Log.i(TAG, "Lifecycle.Event.ON_CREATE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart() {
        Log.i(TAG, "Lifecycle.Event.ON_START")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        Log.i(TAG, "Lifecycle.Event.ON_RESUME")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        Log.i(TAG, "Lifecycle.Event.ON_PAUSE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
        Log.i(TAG, "Lifecycle.Event.ON_STOP")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        Log.i(TAG, "Lifecycle.Event.ON_DESTROY")
    }
}

② 自定义 Application


在该 自定义 Application 类中 , 调用 ProcessLifecycleOwner#getLifecycle#addObserver 函数 , 为整个应用的 Activity 组件添加监听 ;

核心代码 :

        ProcessLifecycleOwner
            .get()
            .lifecycle
            .addObserver(MyLifeCycleObserver())

完整代码 :

package kim.hsl.lifecycle

import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner

class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()

        ProcessLifecycleOwner
            .get()
            .lifecycle
            .addObserver(MyLifeCycleObserver())
    }
}

③ AndroidManifest.xml 清单文件配置


在清单文件中 , 设置自定义的 MyApplication , 为 application 节点添加

android:name=".MyApplication"

属性 ;

完整代码 :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LifeCycleDemo"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

④ 执行效果


应用打开后 , 打印日志 :

2023-03-03 18:08:20.368 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_CREATE
2023-03-03 18:08:20.577 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_START
2023-03-03 18:08:20.580 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_RESUME

按下 Home 键 , 应用进入后台 , 打印日志 :

2023-03-03 18:11:11.712 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_PAUSE
2023-03-03 18:11:11.713 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_STOP

再次回到前台 , 打印日志 :

2023-03-03 18:11:26.761 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_START
2023-03-03 18:11:26.764 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_RESUME

杀掉进程 , 打印日志 :

2023-03-03 18:11:46.490 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_PAUSE
2023-03-03 18:11:46.490 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_STOP

完整日志信息 :

2023-03-03 18:08:20.368 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_CREATE
2023-03-03 18:08:20.577 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_START
2023-03-03 18:08:20.580 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_RESUME


2023-03-03 18:11:11.712 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_PAUSE
2023-03-03 18:11:11.713 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_STOP


2023-03-03 18:11:26.761 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_START
2023-03-03 18:11:26.764 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_RESUME

2023-03-03 18:11:46.490 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_PAUSE
2023-03-03 18:11:46.490 18539-18539/kim.hsl.lifecycle I/LifecycleDemo: Lifecycle.Event.ON_STOP

在这里插入图片描述


博客代码 : https://download.csdn.net/download/han1202012/87527626

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么北欧的顶级程序员数量远超中国?

说起北欧&#xff0c;很多人会想到寒冷的冬天&#xff0c;漫长的极夜&#xff0c;童话王国和圣诞老人&#xff0c;但是如果我罗列下诞生于北欧的计算机技术&#xff0c;恐怕你会惊掉下巴。Linux&#xff1a;世界上最流行的开源操作系统&#xff0c;最早的内核由Linus Torvalds开…

2022济南大学acm新生赛题解

通过答题情况的难度系数&#xff1a; 签到&#xff1a;ABL 简单&#xff1a;DGKQ 中等&#xff1a;CMN 困难&#xff1a;EFHIJOPRST A-和 算出n个数的和判断正负性即可&#xff01;&#xff01;&#xff01; 发现很多同学的代码错误&#xff1a;要么sum未赋初值&#xf…

DDOS攻击

注&#xff1a;本博客只是为了自己的学习&#xff0c;记录自己的学习&#xff0c;请勿用于其他途径、1、winR-->cmd2、ping 网站3、替换IP1 import java.io.BufferedInputStream;2 import java.io.IOException;3 import java.net.MalformedURLException;4 import java.net.U…

Vue3做出B站【bilibili】 Vue3+TypeScript+ant-design-vue【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScriptant-design-vue【快速入门一篇文章精通系列&#xff08;一&…

【C++】STL简介 及 string的使用

文章目录1. STL简介1.1 什么是STL1.2 STL的版本1.3 STL的六大组件2. string类的使用2.1 C语言中的字符串2.2 标准库中的string类2.3 string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作3. string类对象的修改操作4. resize和reserve5. 认识迭代器&…

产品研发项目进度管理软件工具有哪些推荐?整理10款最佳进度管理软件

项目进度管理是确保项目按时完成的关键过程&#xff0c;使用合适的项目进度管理工具能确保帮助项目管理者实时了解和控制项目的进展情况&#xff0c;及时发现和解决问题&#xff0c;减少项目风险&#xff0c;提高项目效率和管理水平。这里将整理出国内外最受欢迎的10款项目进度…

ASEMI低压MOS管SI2301参数,SI2301体积,SI2301尺寸

编辑-Z ASEMI低压MOS管SI2301参数&#xff1a; 型号&#xff1a;SI2301 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;20V 栅源电压&#xff08;VGS&#xff09;&#xff1a;8V 漏极电流&#xff08;ID&#xff09;&#xff1a;2.3A 功耗&#xff08;PD&#xf…

Simulink壁咚(一)——What and How

目录 一、前言 二、Simulink 知多少 三、滤波算法 四、Model Verification 五、Model Coverage 六、Simulink测试实例 七、Simulink Test 八、Test Manager 九、Test Harness 十、 学习 一、前言 Simulink从2017b以后更加工程化和实用化&#xff0c;基于MBD的功能日趋…

MATLAB绘制ROC曲线

ROC曲线(Receiver Operating Characteristic Curve) 1 简介 ROC曲线是用于评估二元分类模型&#xff08;如Logistic回归&#xff09;表现优劣的一种工具&#xff0c;其横轴表示假阳性率&#xff08;false positive rate&#xff0c;FPR&#xff09;&#xff0c;即实际为负例但…

MySQL事务详解

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;Spring事务和MySQL事务详解 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: …

vue3 构建属于自己的组件库dxui

文章目录前言第一步&#xff0c;通过vue-cli搭建vue3框架第二步&#xff0c;构建一个入口&#xff0c;将所有的组件统一管理第三步 修改package.json &#xff0c;对组件进行单独打包第四步输入命令行开始打包第五步&#xff0c;修改package.json文件&#xff0c;为npm 发布做准…

[ vulnhub靶机通关篇 ] 渗透测试综合靶场 DC-1 通关详解 (附靶机搭建教程)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Python 基础教程【1】:Python介绍、变量和数据类型、输入输出、运算符

本文已收录于专栏&#x1f33b;《Python 基础》文章目录1、Python 介绍2、变量和数据类型2.1 注释的使用2.2 变量以及数据类型2.2.1 什么是变量&#xff1f;2.2.2 怎么给变量起名&#xff1f;2.2.3 变量的类型&#x1f3a8; 整数 int&#x1f3a8; 浮点数&#xff08;小数&…

教你成为比卡卡西还牛逼的全能忍者,全拷贝与分割函数

如何成为一个集雷切&#xff0c;写轮眼侦查和拷贝与一身的卡卡西&#xff0c;下面教你&#xff01; 目录 第一式——雷切&#xff01; strtok 第二式——写轮眼侦查&#xff01; strerror函数 第三式——写轮眼拷贝&#xff01; memcpy 模拟实现memcpy函数 &#x1f60e;…

Hadoop集群搭建

文章目录一、运行环境配置(所有节点)1、基础配置2、配置Host二、依赖软件安装(101节点)1、安装JDK2、安装Hadoop(root)3、Hadoop目录结构三、本地运行模式&#xff08;官方WordCount&#xff09;1、简介2、本地运行模式&#xff08;官方WordCount&#xff09;四、完全分布式运行…

多线程的风险 --- 线程安全

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; ✨每日一语&#xff1a;低头赶路&#xff0c;敬事如仪&#xff1b;自知自心&#xff0c;其路则明。 目 录&#x1f378;一. 线程不安全&#x1f379;二. 线程不安全的原因&#x1f…

看完书上的栈不过瘾,为什么不动手试试呢?

一.栈的基本概念1.栈的定义栈&#xff08;Stack&#xff09;&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。其中注意几点&#xff1a;栈顶&#xff08;Top&#xff09;&#xff1a;线性表…

【C语言蓝桥杯每日一题】—— 单词分析

【C语言蓝桥杯每日一题】—— 单词分析&#x1f60e;前言&#x1f64c;单词分析&#x1f64c;总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者…

三天吃透MySQL面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

C 语言编程 — 线程池设计与实现

目录 文章目录目录线程池&#xff08;Thread Pool&#xff09;tiny-threadpool数据结构设计Task / JobTask / Job QueueWorker / ThreadThread Pool ManagerPublic APIsPrivate Functions运行示例线程池&#xff08;Thread Pool&#xff09; 线程池&#xff08;Thread Pool&am…
最新文章