Merge remote-tracking branch 'origin/master'

This commit is contained in:
Quyunshuo
2021-01-07 17:02:26 +08:00
5 changed files with 148 additions and 25 deletions

View File

@ -1,15 +1,13 @@
package com.quyunshuo.base.mvvm.v package com.quyunshuo.base.mvvm.v
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.base.utils.BindingReflex
import com.quyunshuo.base.utils.EventBusRegister import com.quyunshuo.base.utils.EventBusRegister
import com.quyunshuo.base.utils.EventBusUtils import com.quyunshuo.base.utils.EventBusUtils
import java.lang.reflect.ParameterizedType
/** /**
* @Author: QuYunShuo * @Author: QuYunShuo
@ -21,16 +19,11 @@ abstract class BaseFrameActivity<VB : ViewBinding, VM : ViewModel> :
AppCompatActivity(), FrameView<VB> { AppCompatActivity(), FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
val vbClass: Class<VB> = BindingReflex.reflexViewBinding(javaClass, layoutInflater)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
inflate.invoke(null, layoutInflater) as VB
} }
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
val vmClass: Class<VM> = BindingReflex.reflexViewModel(javaClass, this)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
ViewModelProvider(this).get(vmClass)
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.base.utils.BindingReflex
import com.quyunshuo.base.utils.EventBusRegister import com.quyunshuo.base.utils.EventBusRegister
import com.quyunshuo.base.utils.EventBusUtils import com.quyunshuo.base.utils.EventBusUtils
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
@ -22,15 +23,11 @@ import java.lang.reflect.ParameterizedType
abstract class BaseFrameFragment<VB : ViewBinding, VM : ViewModel> : Fragment(), FrameView<VB> { abstract class BaseFrameFragment<VB : ViewBinding, VM : ViewModel> : Fragment(), FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
val vbClass: Class<VB> = BindingReflex.reflexViewBinding(javaClass, layoutInflater)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
inflate.invoke(null, layoutInflater) as VB
} }
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
val vmClass: Class<VM> = BindingReflex.reflexViewModel(javaClass, this)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
ViewModelProvider(this).get(vmClass)
} }
override fun onCreateView( override fun onCreateView(

View File

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.base.utils.BindingReflex
import com.quyunshuo.base.utils.EventBusRegister import com.quyunshuo.base.utils.EventBusRegister
import com.quyunshuo.base.utils.EventBusUtils import com.quyunshuo.base.utils.EventBusUtils
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
@ -19,10 +20,7 @@ abstract class BaseFrameNotMVVMActivity<VB : ViewBinding> : AppCompatActivity(),
FrameNotMVVMView<VB> { FrameNotMVVMView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
val vbClass: Class<VB> = BindingReflex.reflexViewBinding(javaClass, layoutInflater)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
inflate.invoke(null, layoutInflater) as VB
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -7,6 +7,7 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.base.utils.BindingReflex
import com.quyunshuo.base.utils.EventBusRegister import com.quyunshuo.base.utils.EventBusRegister
import com.quyunshuo.base.utils.EventBusUtils import com.quyunshuo.base.utils.EventBusUtils
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
@ -20,10 +21,7 @@ import java.lang.reflect.ParameterizedType
abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> { abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
val vbClass: Class<VB> = BindingReflex.reflexViewBinding(javaClass, layoutInflater)
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VB>
val inflate = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
inflate.invoke(null, layoutInflater) as VB
} }
override fun onCreateView( override fun onCreateView(

View 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初始化失败")
}
}