我正在尝试使用Android架构组件编写示例应用程序,但即使在尝试了几天之后,我也无法让它工作。它给了我以上例外。
生命周期所有者: -
public class MainActivity extends LifecycleActivity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_user);
PostViewModel viewModel = ViewModelProviders.of(this).get(PostViewModel.class);
viewModel.loadPosts();
viewModel.getPost().observe(this, new Observer<Post>() {
@Override
public void onChanged(@Nullable Post post) {
if(post != null) {
textView.setText(post.toString());
}
}
});
}
}
视图模型: -
public class PostViewModel extends ViewModel {
private MediatorLiveData<Post> post;
private PostRepository postRepo;
PostViewModel() {
post = new MediatorLiveData<>();
postRepo = new PostRepository();
}
public LiveData<Post> loadPosts() {
post.addSource(postRepo.getPost(),
post -> this.post.setValue(post)
);
return post;
}
@NonNull
public LiveData<Post> getPost() {
return post;
}
}
答案 0 :(得分:52)
制作构造函数public
。
答案 1 :(得分:15)
如果您使用的是Hilt
,请确保您的活动/片段带有@AndroidEntryPoint
注释
答案 2 :(得分:9)
在Google的roomdb CodeLab之后,我遇到了这个问题。解决方案正在更改以下内容。
将以下构建依赖项添加到Gradle文件中(自2020年2月22日开始)
implementation 'androidx.fragment:fragment:1.2.2'
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'androidx.lifecycle:lifecycle-service:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0'
在片段内导入
import androidx.lifecycle.ViewModelProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
创建viewModel。添加以下方法之一。
注意:我看过很多方法。我相信正确的方法是使用getDefaultViewModelProviderFactory()
。但是我一直在使用requireActivity()
。
new ViewModelProvider(requireActivity(),getDefaultViewModelProviderFactory()).get(YourViewModel.class);
|
new ViewModelProvider(requireActivity()).get(YourViewModel.class);
已折旧
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc01'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.2.0-rc01'
答案 3 :(得分:8)
请确保您的ViewModel
的构造函数仅带有一个参数,即Application
。
示例:
public YourViewModel(Application application) {
super(application);
...
答案 4 :(得分:6)
DggerHilt 也可能是原因,如果您正在使用它,请确保您的 activity/fragment
上有 @AndroidEntryPoint
注释。
答案 5 :(得分:5)
如果您使用的是Kotlin
,请确保将annotationProcessor
中的任何build.gradle
替换为kapt
。
赞:
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
将成为
kapt "android.arch.persistence.room:compiler:$rootProject.roomVersion"
并添加
apply plugin: 'kotlin-kapt'
位于buidl.gradle
文件的顶部。
答案 6 :(得分:4)
对我来说这并不是很明显,但是当我收到此错误时,我通过创建公共构造函数来解决它。我的构造函数源自Android Developer示例,并包含Repository作为参数。创建一个空的没有参数并将其公开的其他构造函数解决了这个问题。
即,在你的情况下
public PostViewModel() {}
答案 7 :(得分:3)
确保使用 hiltNavGraphViewModel
而不是 viewModel
。
这是由 androidx.hilt:hilt-navigation-compose
依赖项提供的。
docs 中有更多详细信息。
答案 8 :(得分:3)
如果您使用的是Hilt,请不要忘记添加这四个依赖项。
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha01"
注意:-如果缺少这些依赖项,您将得到Cannot create an instance of class ViewModel
错误
答案 9 :(得分:2)
让类和构造函数公开它解决了我的问题。
答案 10 :(得分:2)
没有什么理由抛出异常。我提到了其中一些。
确保您的视图模型类的构造函数是公共的
确保已在网格文件中添加了以下项的依赖项: 如果您使用了房间和其他壁橱,也将获得生命周期。.
答案 11 :(得分:1)
如果您在 Kotlin Dagger Hilt 中遇到此问题,即使在使用 @HiltViewModel 并使用 @Inject 之后,请确保您已更新所有刀柄依赖项。
答案 12 :(得分:1)
如果您正在使用 Hilt 依赖注入,您可能已经错过了 @ViewModelInject。因为,Hilt 为视图模型提供了自己的注入。
在我的例子中,我使用了 @Inject 因为这陷入了错误。
答案 13 :(得分:1)
就我而言,这是一个依赖关系问题。
如果您正在使用Livedata,
build.gradle(Module.app)
不是
implementation 'android.arch.lifecycle:extensions:1.1.1'
kapt 'android.arch.lifecycle:common-java8:1.1.1'
使用这些
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
kapt 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
答案 14 :(得分:0)
在我的情况下,原因是我试图在创建活动之前不久将片段中ViewModel的共享实例获取。当应用程序被杀死后恢复其状态时,就会发生这种情况。
前提条件:
活动代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//factory is constructed using Dagger
val factory = App.get().components().appComponent.getMapViewModelFactory()
//activity creates the instance of MapViewModel
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
}
代码片段:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//fragment receives the instance of MapViewModel
viewModel = ViewModelProviders.of(activity!!)[MapViewModel::class.java]
...
}
当我第一次打开应用程序时,一切正常:活动创建ViewModel实例;我打开Fragment,它获取ViewModel的实例。但是,当应用程序被杀死后试图恢复其状态时,它首先调用Fragment的onCreate主体,然后调用Activity的onCreate主体。到那时,片段无法获取ViewModel,因为Activity尚未创建它。
解决方案1 :当片段将ViewModel从onCreate移到onViewCreated时,移动代码。就像我在onViewCreated中观察所有liveData一样,这很好。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = activity?.run { ViewModelProviders.of(this)[MapViewModel::class.java] } ?: throw Exception("Invalid Activity")
viewModel.getSurveyDateLiveData().observe(viewLifecycleOwner, Observer<String> { dateTextView.text = it })
...
}
解决方案2 : 在调用 super.onCreate 之前,在 Activity.onCreate 中创建ViewModel实例。在这种情况下,您可以在片段的 onCreate 中获取ViewModel。
override fun onCreate(savedInstanceState: Bundle?) {
val factory = App.get().components().appComponent.getMapViewModelFactory()
viewModel = ViewModelProviders.of(this, factory)[MapViewModel::class.java]
super.onCreate(savedInstanceState)
Timber.d("cc: onCreate: $this ")
}
答案 15 :(得分:0)
我有同样的问题,尝试了许多方法,最后我找到了它。这是我的BASE_URL:
public static final String BASE_URL = "https://ipsquotes.herokuapp.com/oidcs";
修改
public static final String BASE_URL = "https://ipsquotes.herokuapp.com/oidcs/";
而且有效,很有趣,对:((.。我认为您应该检查BASE_URL以确保其格式正确
答案 16 :(得分:0)
创建一个没有参数且为空的附加构造函数 公开解决该问题。
答案 17 :(得分:0)
我的问题是IDE在ViewModel类中添加了“ 抽象”修饰符。
答案 18 :(得分:0)
对于我来说,我需要使用ListItemViewModelFactory来将参数传递给我的视图模型。
答案 19 :(得分:0)
设置ViewModal类并构造公共
答案 20 :(得分:0)
如果您的视图模型的构造函数是公共的,并且仅接受应用程序,那么请确保您可以在没有ViewModelProvider
的情况下创建自己的模型。错误消息可能更加清晰:
val model = YouViewModel(app)
答案 21 :(得分:0)
如果您的PostViewModel类是一个内部类,请确保其公共和静态
答案 22 :(得分:0)
我正在使用此示例android-arcuitecture-component BasicSample来创建一个新项目,面临类似的错误日志,发现我没有更改申请名称
AndroidManifest.xml
那是我的错误,要修复aplicacion名称为de BasicApp,该类在示例中是实现。
...
<application
android:name=".BasicApp"
android:allowBackup="false"
答案 23 :(得分:0)
我是一位熟练的Android开发人员,并且使用ViewModel已有100多次,没有任何问题。今天我遇到了这个问题。花了几个小时,浏览了各种SO帖子。没解决。
然后我看到其中装有ViewModel的程序包名称包含new
。像这样:
com.myapp.myfeature.new.feature
我将new
更改为neww
进行了如下测试:
com.myapp.myfeature.neww.feature
成功了!我希望有人觉得它有用。
答案 24 :(得分:0)
如果您在活动中使用了viewmodel,请检查您的活动是否扩展了“ DaggerAppCompatActivity”
例如
public class UserComments extends AppCompatActivity
将此更改为
public class UserComments extends DaggerAppCompatActivity
答案 25 :(得分:0)
从ViewModel类扩展 AndroidViewModel 。
public class YourViewModel extends AndroidViewModel {
public YourViewModel(Application application) {
super(application);
//Todo: ...
}
}
答案 26 :(得分:0)
如果您使用的是 2.33-beta 和 upper 版本,请删除这些依赖项;
OnPause
只保留这两个依赖
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"
答案 27 :(得分:0)
我在迁移到AndroidX后得到了这个。
androidx.lifecycle:lifecycle-viewmodel:2.0.0-beta01
中存在一个错误,其中Proguard删除了构造函数。
https://issuetracker.google.com/issues/112230489
通过升级到2.0.0修复,并记住在需要时更新您的proguard规则。
我的错误消息如下:
java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:202)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
......
Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application]
at java.lang.Class.getConstructor0(Class.java:2204)
at java.lang.Class.getConstructor(Class.java:1683)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
... 34 more
androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 539, 1167 and precision: 16, 16' on view 'with id: my.test:id/button_return_to_main_menu'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:82)
at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79)
.....
Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{my.custom.domain.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class my.custom.viewmodel.CustomViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
答案 28 :(得分:0)
答案 29 :(得分:-1)
请添加以下代码。对我有用
val binding = FragmentLayoutBinding.inflate(inflater, container, false)
val viewModel = ViewModelProvider(
requireActivity(),
defaultViewModelProviderFactory
).get(MainViewModel::class.java)