android - Cannot create instance of class ViewModel while using MVVM
问题描述
I have created ViewModel
class, and trying to create an instance of my
ViewModel
class using ViewModelProvider. At runtime, I'm getting this error
"Cannot create an instance of class className ViewModel
. Here are the
required codes:
MainActivity.java
public class MainActivity extends AppCompatActivity {
MainActivityViewModel mainActivityViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
}
}
MainActivityViewModel.java
public class MainActivityViewModel extends AndroidViewModel {
private BookShopRepository bookShopRepository;
public MainActivityViewModel(@NonNull Application application) {
super(application);
bookShopRepository = new BookShopRepository(application);
}
}
BookShopRepository.java
public class BookShopRepository {
private CategoryDAO categoryDAO;
private BookDAO bookDAO;
private LiveData<List<Category>> categories;
private LiveData<List<Book>> books;
public BookShopRepository(Application application) {
BooksDatabase booksDatabase = BooksDatabase.getInstance(application);
categoryDAO = booksDatabase.categoryDAO();
bookDAO = booksDatabase.bookDAO();
}
}
build.gradle dependencies
dependencies {
def room_version = "2.2.5"
def lifecycle_version = "2.2.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
ERROR MESSAGE:
Process: com.example.ch5project, PID: 3754
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ch5project/com.example.ch5project.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.ch5project.viewmodel.MainActivityViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.ch5project.viewmodel.MainActivityViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.ch5project.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.InstantiationException: class com.example.ch5project.viewmodel.MainActivityViewModel has no zero argument constructor
at java.lang.Class.newInstance(Class.java:1597)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.ch5project.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor(Class.java:531)
at java.lang.Class.getDeclaredConstructor(Class.java:510)
at java.lang.Class.newInstance(Class.java:1595)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.ch5project.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
```text
解决方案
As per the Lifecycle 2.2.0 release notes:
ViewModelProviders.of()
deprecation:ViewModelProviders.of()
has been deprecated. You can pass aFragment
orFragmentActivity
to the newViewModelProvider(ViewModelStoreOwner)
constructor to achieve the same functionality when using Fragment 1.2.0.
That last part is important, as otherwise new ViewModelProvider(this)
will only use the NewInstanceFactory
you see in the exception, which doesn't support AndroidViewModel
. AppCompat 1.1.0 only depends on Fragment 1.1.0, so you're not getting the support for the ViewModelProvider
constructor you're using.
Therefore, you should upgrade to Fragment 1.2.0 or higher (currently 1.2.4):
implementation 'androidx.fragment:fragment:1.2.4'
推荐阅读
- mysql - 如果我无法触及插入查询,有没有办法在 sql 中回滚失败的批量插入?也许触发?
- javascript - 为什么我的对象没有被推入不同的数组?
- angular - Angular - 这是编写初始化函数的另一种方式吗?
- java - Java JDBC mysql中的更新查询不起作用
- python - 为什么我可以打印到命令行但不能使用 docker 写入文本文件?
- java - 为什么我自己的 AtomicLong 比 JDK 中提供的要慢?
- javascript - 为什么在条件渲染中解析 Math.mod() 的错误?
- python - 有没有办法在包含字符串的对象数组上使用 numpy 字符串数组函数?
- react-native - 为什么在使用 Firebase 注册用户时,Android 和 IOS 设备模拟器之间存在差异?
- c++ - 在 std::list 中,std::distance(it.begin(), std::prev(it.end())) 是否等于 list.size()?