Skip to content

Commit

Permalink
fix: diff fragment lifecycle and viewLifecycleOwner (#15, #13)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-dhl committed Jan 25, 2021
1 parent eabfbf4 commit 77ee11b
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package androidx.lifecycle

/**
* <pre>
* author: dhl
* date : 2021/1/25
* desc :
* </pre>
*/

open class BindingLifecycleObserver : FullLifecycleObserver {

override fun onCreate(owner: LifecycleOwner) {
}

override fun onStart(owner: LifecycleOwner) {
}

override fun onResume(owner: LifecycleOwner) {
}

override fun onPause(owner: LifecycleOwner) {
}

override fun onStop(owner: LifecycleOwner) {
}

override fun onDestroy(owner: LifecycleOwner) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.viewbinding.ViewBinding
import com.hi.dhl.binding.LifecycleFragment
import com.hi.dhl.binding.addObserver
import com.hi.dhl.binding.registerActivityLifecycleCallbacks
import com.hi.dhl.binding.observerWhenDestroyed
import kotlin.properties.ReadOnlyProperty

/**
Expand All @@ -28,10 +27,10 @@ abstract class ActivityDelegate<T : ViewBinding>(

init {
when (activity) {
is ComponentActivity -> activity.lifecycle.addObserver { destroyed() }
is ComponentActivity -> activity.lifecycle.observerWhenDestroyed { destroyed() }
else -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity.registerActivityLifecycleCallbacks { destroyed() }
activity.observerWhenDestroyed { destroyed() }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.hi.dhl.binding.base
import android.app.Dialog
import androidx.lifecycle.Lifecycle
import androidx.viewbinding.ViewBinding
import com.hi.dhl.binding.addObserver
import com.hi.dhl.binding.observerWhenDestroyed
import kotlin.properties.ReadOnlyProperty

/**
Expand All @@ -20,7 +20,7 @@ abstract class DialogDelegate<T : ViewBinding>(
protected var viewBinding: T? = null

init {
lifecycle?.addObserver { destroyed() }
lifecycle?.observerWhenDestroyed { destroyed() }
}

fun destroyed() {
Expand Down
19 changes: 17 additions & 2 deletions binding/src/main/java/com/hi/dhl/binding/base/FragmentDelegate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package com.hi.dhl.binding.base

import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.hi.dhl.binding.addObserver
import com.hi.dhl.binding.observerWhenCreated
import com.hi.dhl.binding.observerWhenDestroyed
import kotlin.properties.ReadOnlyProperty

/**
Expand All @@ -19,7 +20,21 @@ abstract class FragmentDelegate<T : ViewBinding>(
protected var viewBinding: T? = null

init {
fragment.lifecycle.addObserver { destroyed() }

/**
* 感谢 architecture-components-samples 提供的思路
*
* 最原始的处理的方案 监听 Fragment 的生命周期,会存在 Fragment 和 Fragment 中的 View 生命周期不一致问题
* 详情查看 [issue][https://github.com/hi-dhl/Binding/issues/15]
*/
fragment.lifecycle.observerWhenCreated {
fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewOwner ->
viewOwner.lifecycle.observerWhenDestroyed {
destroyed()
}
}
}

}

private fun destroyed() {
Expand Down
50 changes: 31 additions & 19 deletions binding/src/main/java/com/hi/dhl/binding/ext/LifecycleExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import android.app.Application
import android.app.Fragment
import android.os.Build
import android.os.Bundle
import androidx.lifecycle.BindingLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner

/**
Expand All @@ -18,32 +18,42 @@ import androidx.lifecycle.LifecycleOwner
* </pre>
*/

fun Lifecycle.addObserver(destroyed: () -> Unit) {
addObserver(LifecycleObserver(this, destroyed))
fun Lifecycle.observerWhenDestroyed(destroyed: () -> Unit) {
addObserver(LifecycleObserver(lifecycle = this, destroyed = destroyed))
}

class LifecycleObserver(var lifecycle: Lifecycle?, val destroyed: () -> Unit) :
LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
val lifecycleState = source.lifecycle.currentState
if (lifecycleState == Lifecycle.State.DESTROYED) {
destroyed()
lifecycle?.apply {
removeObserver(this@LifecycleObserver)
lifecycle = null
}
}
fun Lifecycle.observerWhenCreated(create: () -> Unit) {
addObserver(LifecycleObserver(lifecycle = this, create = create))
}

class LifecycleObserver(
var lifecycle: Lifecycle?,
var destroyed: (() -> Unit)? = null,
var create: (() -> Unit)? = null
) : BindingLifecycleObserver() {

override fun onCreate(owner: LifecycleOwner) {
create?.invoke()
}

override fun onDestroy(owner: LifecycleOwner) {
destroyed?.invoke()
lifecycle?.apply {
removeObserver(this@LifecycleObserver)
lifecycle = null
}
create = null
destroyed = null
}
}

fun Activity.registerActivityLifecycleCallbacks(destroyed: () -> Unit) {
fun Activity.observerWhenDestroyed(destroyed: () -> Unit) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
registerActivityLifecycleCallbacks(LifecycleCallbacks(destroyed))
}
}

class LifecycleCallbacks(val destroyed: () -> Unit) :
class LifecycleCallbacks(var destroyed: (() -> Unit)? = null) :
Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
}
Expand All @@ -64,15 +74,16 @@ class LifecycleCallbacks(val destroyed: () -> Unit) :
}

override fun onActivityDestroyed(activity: Activity) {
destroyed()
destroyed?.invoke()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity.unregisterActivityLifecycleCallbacks(this)
}
destroyed = null
}
}

class LifecycleFragment : Fragment {
lateinit var destroyed: () -> Unit
var destroyed: (() -> Unit)? = null

constructor()

Expand All @@ -83,6 +94,7 @@ class LifecycleFragment : Fragment {

override fun onDestroy() {
super.onDestroy()
destroyed()
destroyed?.invoke()
destroyed = null
}
}

0 comments on commit 77ee11b

Please sign in to comment.