用于ViewModels的自定义半广义工厂
我想创建一个广义的ViewModelProvider.Factory来实例化我的ViewModels
class BundledAppFactory(private var bundle: AppParameterBundle) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { Log.d("Factory", "Creating ${modelClass.canonicalName}") Log.d("Factory", "${modelClass.canonicalName} has ${modelClass.constructors.size} constructors and ${modelClass.declaredConstructors.size} declaredConstructors") modelClass.constructors.forEach { Log.d("Factory", "Constructor: $it") } return when { AppViewModel::class.java.isAssignableFrom(modelClass) -> modelClass.getDeclaredConstructor(AppParameterBundle::class.java).newInstance(bundle) AppTeamUserViewModel::class.java.isAssignableFrom(modelClass) -> modelClass.getDeclaredConstructor(AppTeamUserParameterBundle::class.java).newInstance(bundle) AppTeamUserHuntIdViewModel::class.java.isAssignableFrom(modelClass) -> modelClass.getDeclaredConstructor(AppTeamUserHuntIdParameterBundle::class.java).newInstance(bundle) AppStringViewModel::class.java.isAssignableFrom(modelClass) -> modelClass.getDeclaredConstructor(AppStringParameterBundle::class.java).newInstance(bundle) else -> super.create(modelClass) } } }
这些是我的包:
open class AppParameterBundle(val application: Application) class AppStringParameterBundle(app: Application, val string: String) : AppParameterBundle(app) class AppTeamUserParameterBundle(app: Application, val team: Team, val user: User) : AppParameterBundle(app) class AppTeamUserHuntIdParameterBundle(app: Application, val huntId: String, val team: Team, val user: User) : AppParameterBundle(app)
这些是我用自定义ViewModels扩展的基本ViewModel:
abstract class AppViewModel(bundle: AppParameterBundle) : BaseViewModel(bundle) abstract class AppTeamUserViewModel(bundle: AppTeamUserParameterBundle) : BaseViewModel(bundle) abstract class AppTeamUserHuntIdViewModel(bundle: AppTeamUserHuntIdParameterBundle) : BaseViewModel(bundle) abstract class AppStringViewModel(bundle: AppStringParameterBundle) : BaseViewModel(bundle)
以下是其中一个ViewModel的例子:
class TeamViewModel(bundle: AppParameterBundle) : AppViewModel(bundle) { ... }
我的问题是
modelClass.getDeclaredConstructor(AppParameterBundle::class.java).newInstance(bundle)
不会find任何构造函数和这行
Log.d("Factory", "${modelClass.canonicalName} has ${modelClass.constructors.size} constructors and ${modelClass.declaredConstructors.size} declaredConstructors")
在日志中出现这种情况
mypackage.viewmodels.TeamViewModel has 0 constructors and 0 declaredConstructors
这是我在堆栈跟踪中得到的:
Caused by: java.lang.NoSuchMethodException: [class mypackage.ParameterBundle] at java.lang.Class.getConstructor(Class.java:528) at java.lang.Class.getDeclaredConstructor(Class.java:507) at mypackage.viewmodels.BundledAppFactory.create(FactoriesAndBundles.kt:39) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128) at mypackage.TeamActivity.onCreate(TeamActivity.kt:41)
这是一个Kotlin问题,没有构造函数? 我该如何解决?
这是一个Proguard问题。 我不得不将这行添加到.pro规则文件
-keep class mypackage.** { *; } -keepclassmembers public class mypackage.** { *; }