反射初始化封装
This commit is contained in:
@ -1,15 +1,13 @@
|
||||
package com.quyunshuo.base.mvvm.v
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.base.utils.BindingReflex
|
||||
import com.quyunshuo.base.utils.EventBusRegister
|
||||
import com.quyunshuo.base.utils.EventBusUtils
|
||||
import java.lang.reflect.ParameterizedType
|
||||
|
||||
/**
|
||||
* @Author: QuYunShuo
|
||||
@ -21,16 +19,11 @@ abstract class BaseFrameActivity<VB : ViewBinding, VM : ViewModel> :
|
||||
AppCompatActivity(), FrameView<VB> {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vbClass: Class<VB> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
|
||||
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
|
||||
inflate.invoke(null, layoutInflater) as VB
|
||||
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
|
||||
}
|
||||
|
||||
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vmClass: Class<VM> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
|
||||
ViewModelProvider(this).get(vmClass)
|
||||
BindingReflex.reflexViewModel(javaClass, this)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.base.utils.BindingReflex
|
||||
import com.quyunshuo.base.utils.EventBusRegister
|
||||
import com.quyunshuo.base.utils.EventBusUtils
|
||||
import java.lang.reflect.ParameterizedType
|
||||
@ -22,15 +23,11 @@ import java.lang.reflect.ParameterizedType
|
||||
abstract class BaseFrameFragment<VB : ViewBinding, VM : ViewModel> : Fragment(), FrameView<VB> {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vbClass: Class<VB> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
|
||||
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
|
||||
inflate.invoke(null, layoutInflater) as VB
|
||||
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
|
||||
}
|
||||
|
||||
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vmClass: Class<VM> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
|
||||
ViewModelProvider(this).get(vmClass)
|
||||
BindingReflex.reflexViewModel(javaClass, this)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
||||
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.base.utils.BindingReflex
|
||||
import com.quyunshuo.base.utils.EventBusRegister
|
||||
import com.quyunshuo.base.utils.EventBusUtils
|
||||
import java.lang.reflect.ParameterizedType
|
||||
@ -19,10 +20,7 @@ abstract class BaseFrameNotMVVMActivity<VB : ViewBinding> : AppCompatActivity(),
|
||||
FrameNotMVVMView<VB> {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vbClass: Class<VB> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
|
||||
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
|
||||
inflate.invoke(null, layoutInflater) as VB
|
||||
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@ -7,6 +7,7 @@ import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.base.utils.BindingReflex
|
||||
import com.quyunshuo.base.utils.EventBusRegister
|
||||
import com.quyunshuo.base.utils.EventBusUtils
|
||||
import java.lang.reflect.ParameterizedType
|
||||
@ -20,10 +21,7 @@ import java.lang.reflect.ParameterizedType
|
||||
abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
val vbClass: Class<VB> =
|
||||
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
|
||||
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
|
||||
inflate.invoke(null, layoutInflater) as VB
|
||||
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
||||
137
Lib_Base/src/main/java/com/quyunshuo/base/utils/BindingReflex.kt
Normal file
137
Lib_Base/src/main/java/com/quyunshuo/base/utils/BindingReflex.kt
Normal file
@ -0,0 +1,137 @@
|
||||
package com.quyunshuo.base.utils
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.ViewModelStoreOwner
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import java.lang.RuntimeException
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author DBoy
|
||||
* @date 2020/9/29
|
||||
* Class 描述 : 用于反射获取 ViewModel 和 ViewBinding
|
||||
*/
|
||||
object BindingReflex {
|
||||
/**
|
||||
* 反射获取ViewBinding
|
||||
*
|
||||
* @param <V> ViewBinding 实现类
|
||||
* @param aClass 当前类
|
||||
* @param from layouinflater
|
||||
* @return viewBinding实例
|
||||
</V> */
|
||||
fun <V : ViewBinding> reflexViewBinding(aClass: Class<*>, from: LayoutInflater?): V {
|
||||
try {
|
||||
val actualTypeArguments =
|
||||
(Objects.requireNonNull(aClass.genericSuperclass) as ParameterizedType).actualTypeArguments
|
||||
for (i in actualTypeArguments.indices) {
|
||||
val tClass = actualTypeArguments[i] as Class<V>
|
||||
if (ViewBinding::class.java.isAssignableFrom(tClass)) {
|
||||
val inflate = tClass.getMethod("inflate", LayoutInflater::class.java)
|
||||
return inflate.invoke(null, from) as V
|
||||
}
|
||||
}
|
||||
return reflexViewBinding<V>(aClass.superclass, from)
|
||||
} catch (e: NoSuchMethodException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: IllegalAccessException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvocationTargetException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
throw RuntimeException("ViewBinding初始化失败")
|
||||
}
|
||||
|
||||
/**
|
||||
* 反射获取ViewBinding\
|
||||
*/
|
||||
fun <V : ViewBinding> reflexViewBinding(
|
||||
aClass: Class<*>,
|
||||
from: LayoutInflater?,
|
||||
viewGroup: ViewGroup?,
|
||||
b: Boolean
|
||||
): V {
|
||||
try {
|
||||
val actualTypeArguments =
|
||||
(Objects.requireNonNull(aClass.genericSuperclass) as ParameterizedType).actualTypeArguments
|
||||
for (i in actualTypeArguments.indices) {
|
||||
val tClass = actualTypeArguments[i] as Class<V>
|
||||
if (ViewBinding::class.java.isAssignableFrom(tClass)) {
|
||||
val inflate = tClass.getDeclaredMethod(
|
||||
"inflate",
|
||||
LayoutInflater::class.java,
|
||||
ViewGroup::class.java,
|
||||
Boolean::class.javaPrimitiveType
|
||||
)
|
||||
return inflate.invoke(null, from, viewGroup, b) as V
|
||||
}
|
||||
}
|
||||
return reflexViewBinding<ViewBinding>(aClass.superclass, from, viewGroup, b) as V
|
||||
} catch (e: NoSuchMethodException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: IllegalAccessException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvocationTargetException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
throw RuntimeException("ViewBinding初始化失败")
|
||||
}
|
||||
|
||||
/**
|
||||
* 反射获取ViewModel
|
||||
*
|
||||
* @param <VM> ViewModel实现类
|
||||
* @param aClass 当前class
|
||||
* @param owner 生命周期管理
|
||||
* @return ViewModel实例
|
||||
</VM> */
|
||||
fun <VM : ViewModel> reflexViewModel(aClass: Class<*>, owner: ViewModelStoreOwner): VM {
|
||||
try {
|
||||
val actualTypeArguments =
|
||||
(Objects.requireNonNull(aClass.genericSuperclass) as ParameterizedType).actualTypeArguments
|
||||
for (i in actualTypeArguments.indices) {
|
||||
val tClass = actualTypeArguments[i] as Class<VM>
|
||||
if (ViewModel::class.java.isAssignableFrom(tClass)) {
|
||||
return ViewModelProvider(owner)[tClass]
|
||||
}
|
||||
}
|
||||
return reflexViewModel<VM>(aClass.superclass, owner)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
throw RuntimeException("ViewModel初始化失败")
|
||||
}
|
||||
|
||||
/**
|
||||
* 反射获取ViewModel,这个方法只提供给fragment使用.
|
||||
* 如果fragment的父Activity有相同的ViewModel 那么生成的ViewModel将会是同一个实例,做到Fragment与Activity的数据同步,
|
||||
* 或者说是同一个Activity中的多个Fragment同步使用用一个ViewModel达到数据之间的同步。
|
||||
*
|
||||
* @param <VM> ViewModel实现类
|
||||
* @param aClass 当前class
|
||||
* @param fragment fragment 调用 [Fragment.requireActivity] 方法
|
||||
* @return ViewModel实例
|
||||
</VM> */
|
||||
fun <VM : ViewModel> reflexViewModelShared(aClass: Class<*>, fragment: Fragment): VM {
|
||||
try {
|
||||
val actualTypeArguments =
|
||||
(Objects.requireNonNull(aClass.genericSuperclass) as ParameterizedType).actualTypeArguments
|
||||
for (i in actualTypeArguments.indices) {
|
||||
val tClass = actualTypeArguments[i] as Class<VM>
|
||||
if (ViewModel::class.java.isAssignableFrom(tClass)) {
|
||||
return ViewModelProvider(fragment.requireActivity())[tClass]
|
||||
}
|
||||
}
|
||||
return reflexViewModelShared<VM>(aClass.superclass, fragment)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
throw RuntimeException("ViewModel初始化失败")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user