Skip to content

Commit

Permalink
fix: ViewGroup 在 databinding 销毁的时候释放资源,添加声明周期检查 (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-dhl committed May 12, 2022
1 parent 0104c72 commit f20a6d9
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ViewBindCustomView @JvmOverloads constructor(
lateinit var onDialogClickListener: OnDialogClickListener

// 当根布局为 merge 标签,使用此方法进行初始化
val binding: LayoutViewCustomBinding by viewbind(this)
val binding: LayoutViewCustomBinding by viewbind()

// 当根布局是非 merge 标签,使用此方法进行初始化
// val binding: LayoutViewCustomBinding by viewbind()
Expand Down
2 changes: 1 addition & 1 deletion binding/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ dependencies {
implementation "androidx.recyclerview:recyclerview:$recyclerview"
}

apply from: 'gradle-mvn-push.gradle'
//apply from: 'gradle-mvn-push.gradle'
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.hi.dhl.binding.databind
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import com.hi.dhl.binding.base.FragmentDelegate
import com.hi.dhl.binding.inflateMethod
import java.lang.Exception
import kotlin.reflect.KProperty

/**
Expand All @@ -29,6 +31,20 @@ class FragmentDataBinding<T : ViewDataBinding>(

} ?: let {

try {
/**
* 检查目的,是为了防止在 onCreateView() or after onDestroyView() 使用 binding。
* 另外在销毁之后,如果再次使用,由于 delegate property 会被再次初始化出现的异常
*
* 捕获这个异常的原因,是为了兼容之前的版本,防止因为升级,造成崩溃
*/
check(thisRef.viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
"cannot use binding in before onCreateView() or after onDestroyView() from 1.1.4. about [issue](https://github.com/hi-dhl/Binding/issues/31#issuecomment-1109733307)"
}
} catch (e: Exception) {
e.printStackTrace()
}

val bind: T
if (thisRef.view == null) {
// 这里为了兼容在 navigation 中使用 Fragment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.hi.dhl.binding.databind

import android.app.Activity
import android.os.Build
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.viewbinding.ViewBinding
import com.hi.dhl.binding.observerWhenDestroyed
import com.hi.dhl.binding.registerLifecycleBelowQ
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

Expand All @@ -20,11 +25,29 @@ class ViewGroupDataBinding<T : ViewBinding>(
classes: Class<T>,
@LayoutRes val resId: Int,
val inflater: LayoutInflater,
val viewGroup: ViewGroup? = null,
private var block: (T.() -> Unit)? = null
) : ReadOnlyProperty<ViewGroup, T> {

private var viewBinding: T? = null

init {
viewGroup?.apply {
when (context) {
is ComponentActivity -> {
(context as ComponentActivity).lifecycle.observerWhenDestroyed { destroyed() }
}
is Activity -> {
val activity = context as Activity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity.observerWhenDestroyed { destroyed() }
} else {
activity.registerLifecycleBelowQ { destroyed() }
}
}
}
}
}
override fun getValue(thisRef: ViewGroup, property: KProperty<*>): T {
return viewBinding?.run {
this
Expand Down
27 changes: 15 additions & 12 deletions binding/src/main/java/com/hi/dhl/binding/ext/ComponentExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,21 @@ inline fun <reified T : ViewDataBinding> RecyclerView.ViewHolder.databind(noinli

inline fun <reified T : ViewBinding> ViewGroup.databind(@LayoutRes resId: Int) =
ViewGroupDataBinding(
T::class.java,
resId,
LayoutInflater.from(getContext())
classes = T::class.java,
resId = resId,
inflater = LayoutInflater.from(getContext()),
viewGroup = this
)

inline fun <reified T : ViewBinding> ViewGroup.databind(
@LayoutRes resId: Int,
noinline block: (T.() -> Unit)
) = ViewGroupDataBinding(
T::class.java,
resId,
LayoutInflater.from(getContext()),
block
classes = T::class.java,
resId = resId,
inflater = LayoutInflater.from(getContext()),
viewGroup = this,
block = block
)

inline fun <reified T : ViewBinding> Activity.viewbind() =
Expand All @@ -109,13 +111,14 @@ inline fun <reified T : ViewBinding> RecyclerView.ViewHolder.viewbind() =
ViewHolderViewBinding(T::class.java)

inline fun <reified T : ViewBinding> ViewGroup.viewbind() = ViewGroupViewBinding(
T::class.java,
LayoutInflater.from(getContext())
classes = T::class.java,
inflater = LayoutInflater.from(getContext()),
viewGroup = this
)

inline fun <reified T : ViewBinding> ViewGroup.viewbind(viewGroup: ViewGroup) =
ViewGroupViewBinding(
T::class.java,
LayoutInflater.from(getContext()),
viewGroup
classes = T::class.java,
inflater = LayoutInflater.from(getContext()),
viewGroup = viewGroup
)

0 comments on commit f20a6d9

Please sign in to comment.