fix: 修复开启混淆后反射方式初始化导致异常的问题,将反射自动初始化方式变更为子类手动初始化的方式

This commit is contained in:
Quyunshuo
2023-08-20 20:36:04 +08:00
parent 337f7fa15e
commit e0835808e3
9 changed files with 19 additions and 252 deletions

View File

@ -1,9 +1,3 @@
# 避免 ViewBinding 类被混淆导致反射初始化失败
-keep public interface androidx.viewbinding.ViewBinding
-keepclassmembers class * implements androidx.viewbinding.ViewBinding{
*;
}
# AGP 8.x 警告生成
# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.

View File

@ -6,6 +6,7 @@ import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.R
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.*
import com.quyunshuo.androidbaseframemvvm.base.utils.network.AutoRegisterNetListener
@ -22,12 +23,10 @@ import me.jessyan.autosize.AutoSizeCompat
abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppCompatActivity(),
FrameView<VB>, NetworkStateChangeListener {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
protected abstract val mViewModel: VM
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { createVB() }
/**
* 是否有 [RegisterEventBus] 注解,避免重复调用 [Class.isAnnotation]
*/
@ -80,7 +79,7 @@ abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppComp
* @return Unit
*/
override fun networkConnectChange(isConnected: Boolean) {
toast(if (isConnected) "网络已连接" else "网络已断开")
toast(if (isConnected) getString(R.string.base_network_connected) else getString(R.string.base_network_disconnected))
}
override fun onDestroy() {

View File

@ -8,7 +8,6 @@ import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
import com.quyunshuo.androidbaseframemvvm.base.utils.RegisterEventBus
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
@ -40,7 +39,7 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = BindingReflex.reflexViewBinding(javaClass, layoutInflater)
_binding = createVB()
return _binding?.root
}

View File

@ -1,40 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
/**
* @author DBoy 2021/8/5 <p>
* - 文件描述 : 基础状态管理Activity
*/
open class BaseFrameStatusActivity : AppCompatActivity() {
/**
* 基础状态管理帮助类
*/
private var mBaseStatusHelper: ViewStatusHelper? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//注册状态帮助类
mBaseStatusHelper = onRegisterStatusHelper()
//恢复状态数据
mBaseStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
}
/**
* 保存状态
*/
override fun onSaveInstanceState(outState: Bundle) {
mBaseStatusHelper?.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
/**
* 注册状态管理帮助类,子类重写此方法以注册帮助类。
* 每一层都有可能有自己的状态管理帮助类所以继承重写的时候需要将super的对象传入自己的帮助类构造函数中
*/
protected open fun onRegisterStatusHelper(): ViewStatusHelper? {
return null
}
}

View File

@ -1,41 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
/**
* @author DBoy 2021/8/5 <p>
* - 文件描述 : 基础状态管理Fragment
*/
open class BaseFrameStatusFragment : Fragment() {
/**
* 基础状态管理帮助类
*/
private var mBaseStatusHelper: ViewStatusHelper? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//注册状态帮助类
mBaseStatusHelper = onRegisterStatusHelper()
//恢复状态数据
mBaseStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
}
/**
* 保存状态
*/
override fun onSaveInstanceState(outState: Bundle) {
mBaseStatusHelper?.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
/**
* 注册状态管理帮助类,子类重写此方法以注册帮助类。
* 每一层都有可能有自己的状态管理帮助类所以继承重写的时候需要将super的对象传入自己的帮助类构造函数中
*/
protected open fun onRegisterStatusHelper(): ViewStatusHelper? {
return null
}
}

View File

@ -1,5 +1,6 @@
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import androidx.lifecycle.LiveData
import androidx.viewbinding.ViewBinding
/**
@ -11,12 +12,17 @@ import androidx.viewbinding.ViewBinding
interface FrameView<VB : ViewBinding> {
/**
* 初始化View
* 创建 [ViewBinding] 实例
*/
fun createVB(): VB
/**
* 初始化 View
*/
fun VB.initView()
/**
* 订阅LiveData
* 订阅 [LiveData]
*/
fun initObserve()

View File

@ -1,156 +0,0 @@
package com.quyunshuo.androidbaseframemvvm.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.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: Class<Any>
try {
tClass = actualTypeArguments[i] as Class<Any>
} catch (e: Exception) {
continue
}
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: Class<Any>
try {
tClass = actualTypeArguments[i] as Class<Any>
} catch (e: Exception) {
continue
}
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: Class<Any>
try {
tClass = actualTypeArguments[i] as Class<Any>
} catch (e: Exception) {
continue
}
if (ViewModel::class.java.isAssignableFrom(tClass)) {
return ViewModelProvider(owner)[tClass as Class<VM>]
}
}
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: Class<Any>
try {
tClass = actualTypeArguments[i] as Class<Any>
} catch (e: Exception) {
continue
}
if (ViewModel::class.java.isAssignableFrom(tClass)) {
return ViewModelProvider(fragment.requireActivity())[tClass as Class<VM>]
}
}
return reflexViewModelShared<VM>(aClass.superclass, fragment)
} catch (e: Exception) {
e.printStackTrace()
}
throw RuntimeException("ViewModel初始化失败")
}
}

View File

@ -0,0 +1,4 @@
<resources>
<string name="base_network_disconnected">网路已断开</string>
<string name="base_network_connected">网络已连接</string>
</resources>

View File

@ -21,6 +21,8 @@ class MainActivity : BaseActivity<HomeActivityMainBinding, HomeViewModel>() {
*/
override val mViewModel by viewModels<HomeViewModel>()
override fun createVB() = HomeActivityMainBinding.inflate(layoutInflater)
override fun HomeActivityMainBinding.initView() {}
override fun initObserve() {