我很难为我的登录用户界面创建一个数据库。目前正在使用一个本地数据库与房间刚刚开始测试。我将建立一个RESTAPI和远程数据库后,一旦完成测试。虽然我已经能够让它在其他教程中工作,但似乎所有的类都在同一个包中。在我正在构建的当前应用程序中,我将包分为类的类型,即活动、片段、dao、viewmodels、接口、适配器等。在我尝试初始化viewmodel中的db之前,一切正常。使用调试器,我可以看到在getdatabase函数执行期间,示例一直为null,直到.build()出现崩溃。
以下是异常日志:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.whatever, PID: 13042
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.whatever/com.example.whatever.activities.LoginActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.whatever.viewModels.ViewModelEmailLogin
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2988)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1534)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1424)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.whatever.viewModels.ViewModelEmailLogin
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:275)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.whatever.ui.fragments.EmailLoginFragment.onCreateView(EmailLoginFragment.java:74)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:310)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2617)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2569)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256)
at android.app.Activity.performStart(Activity.java:6959)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2890)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2988)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1534)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1424)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.whatever.ui.fragments.EmailLoginFragment.onCreateView(EmailLoginFragment.java:74)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:310)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2617)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2569)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256)
at android.app.Activity.performStart(Activity.java:6959)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2890)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2988)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1534)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1424)
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.whatever.db.WhatEverUserDB. WhatEverUserDB_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:94)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:952)
at com.example.whatever.db.WhatEverUserDB.getDatabase(WhatEverUserDB.java:45)
at com.example.whatever.repositories.WhatEverUserRepo.<init>(WhatEverUserRepo.java:33)
at com.example.whatever.viewModels.ViewModelEmailLogin.<init>(ViewModelEmailLogin.java:31)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.whatever.ui.fragments.EmailLoginFragment.onCreateView(EmailLoginFragment.java:74)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:310)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2617)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2569)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256)
at android.app.Activity.performStart(Activity.java:6959)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2890)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2988)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1534)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1424)
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
模型
package com.example.whatever.db;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
// This is an object used to create a WhatEver User
//debating if we should use WhatEver user to link to other social media accounts
// we could create lists of social sites with accounts that gather the info from the db
import java.util.List;
@Entity(tableName = "whatever_user_table")
public class WhatEverUser {
@PrimaryKey(autoGenerate = true)// with each new row we add to the db, room will automatically create a new id
private int ID;
private CharSequence Username;
private CharSequence Email;
private CharSequence Password;
public WhatEverUser(CharSequence Username, CharSequence Email, CharSequence Password){
this.Username = Username;
this.Email = Email;
this.Password = Password;
}
public CharSequence getPassword() {
return Password;
}
public CharSequence getEmail() {
return Email;
}
public CharSequence getUsername() {
return Username;
}
public int getID() {
return ID;
}
public void setUsername(CharSequence username) {
this.Username = username;
}
public void setPassword(CharSequence password) {
Password = password;
}
public void setID(int ID) {
this.ID = ID;
}
public void setEmail(CharSequence email) {
this.Email = email;
}
}
分贝
package com.example.whatever.db;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.Database;
import androidx.sqlite.db.SupportSQLiteDatabase;
import com.example.whatever.interfaces.WhatEverUserDAO;
import com.example.whatever.db.WhatEverUser;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Database(entities = {WhatEverUser.class},version = 1)
public abstract class WhatEverUserDB extends RoomDatabase {
private static volatile WhatEverUserDB INSTANCE; // this is an instance of our database
public abstract WhatEverUserDAO whatEverUserDAO(); //we use this method to access our dao
// we use this method to access our db methods in the dao
private static final int NUMBER_OF_THREADS = 4;
static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static WhatEverUserDB getDatabase(final Context context){
if (INSTANCE == null){
synchronized (WhatEverUserDB.class){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WhatEverUserDB.class,
"whatever_user_table")
.allowMainThreadQueries()
.addCallback(roomCallback)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
databaseWriteExecutor.execute(() -> {
WhatEverUserDAO whatEverUserDAO = INSTANCE.whatEverUserDAO();
WhatEverUser admin = new WhatEverUser("admin","admin@admin.com","password");
whatEverUserDAO.insertUser(admin);
WhatEverUser test1 = new WhatEverUser("test1","test1@test1.com","test1234");
whatEverUserDAO.insertUser(test1);
});
}
};
}
//creating the database
/* public static synchronized whatEverUserDB getInstance(final Context context){ //we create our only db instance, synchronized means only one thread can access this db at a time.
if (instance == null){
instance = Room.databaseBuilder(context.getApplicationContext(), whatEverUserDB.class, "whatever_user_database")
//.enableMultiInstanceInvalidation()
//.allowMainThreadQueries()
.fallbackToDestructiveMigration() //if we don't do this and try to increase the version, the app will crash, this avoids this by deleting the tables and starting from scratch
//.addCallback(roomCallback)
.build();
}
return instance;
}
*/
/* private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
// new PopulateDBAsyncTask(instance).execute();
}
};
private static class PopulateDBAsyncTask extends AsyncTask<Void, Void, Void> { // Creating this async task to populate the db for test users
private WhatEverUserDAO whatEverUserDAO;
private PopulateDBAsyncTask(whatEverUserDB db){
whatEverUserDAO = db.whatEverUserDAO();
}
@Override
protected Void doInBackground(Void... voids) {
whatEverUserDAO.insertUser(new WhatEverUser("admin","admin@admin.com","password"));
whatEverUserDAO.insertUser(new WhatEverUser("test1","admin1@admin.com","password"));
whatEverUserDAO.insertUser(new WhatEverUser("test2","admin2@admin.com","password"));
return null;
}
}
* /
// must extend roomDb and be abstract
// version must be changed every time we create a new db from scratch
// we should not leave userDB on devices, this will eventually need to be grabbed from our own sql server so this class may be removed later TODO
刀
package com.example.whatever.db;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.Database;
import androidx.sqlite.db.SupportSQLiteDatabase;
import com.example.whatever.interfaces.WhatEverUserDAO;
import com.example.whatever.db.WhatEverUser;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Database(entities = {WhatEverUser.class},version = 1)
public abstract class WhatEverUserDB extends RoomDatabase {
private static volatile WhatEverUserDB INSTANCE; // this is an instance of our database
public abstract WhatEverUserDAO whatEverUserDAO(); //we use this method to access our dao
// we use this method to access our db methods in the dao
private static final int NUMBER_OF_THREADS = 4;
static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static WhatEverUserDB getDatabase(final Context context){
if (INSTANCE == null){
synchronized (WhatEverUserDB.class){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WhatEverUserDB.class,
"whatever_user_table")
.allowMainThreadQueries()
.addCallback(roomCallback)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
databaseWriteExecutor.execute(() -> {
WhatEverUserDAO whatEverUserDAO = INSTANCE.whatEverUserDAO();
WhatEverUser admin = new WhatEverUser("admin","admin@admin.com","password");
whatEverUserDAO.insertUser(admin);
WhatEverUser test1 = new WhatEverUser("test1","test1@test1.com","test1234");
whatEverUserDAO.insertUser(test1);
});
}
};
}
//creating the database
/* public static synchronized whatEverUserDB getInstance(final Context context){ //we create our only db instance, synchronized means only one thread can access this db at a time.
if (instance == null){
instance = Room.databaseBuilder(context.getApplicationContext(), whatEverUserDB.class, "whatever_user_database")
//.enableMultiInstanceInvalidation()
//.allowMainThreadQueries()
.fallbackToDestructiveMigration() //if we don't do this and try to increase the version, the app will crash, this avoids this by deleting the tables and starting from scratch
//.addCallback(roomCallback)
.build();
}
return instance;
}
*/
/* private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
// new PopulateDBAsyncTask(instance).execute();
}
};
private static class PopulateDBAsyncTask extends AsyncTask<Void, Void, Void> { // Creating this async task to populate the db for test users
private WhatEverUserDAO whatEverUserDAO;
private PopulateDBAsyncTask(whatEverUserDB db){
whatEverUserDAO = db.whatEverUserDAO();
}
@Override
protected Void doInBackground(Void... voids) {
whatEverUserDAO.insertUser(new WhatEverUser("admin","admin@admin.com","password"));
whatEverUserDAO.insertUser(new WhatEverUser("test1","admin1@admin.com","password"));
whatEverUserDAO.insertUser(new WhatEverUser("test2","admin2@admin.com","password"));
return null;
}
}
* /
// must extend roomDb and be abstract
// version must be changed every time we create a new db from scratch
// we should not leave userDB on devices, this will eventually need to be grabbed from our own sql server so this class may be removed later TODO
回购
package com.example.whatever.repositories;
import android.app.Application;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import com.example.whatever.db.WhatEverUser;
import com.example.whatever.db.WhatEverUserDB;
import com.example.whatever.interfaces.WhatEverUserDAO;
import androidx.lifecycle.LiveData;
// UserRepo connects the view model to the room. Transmits LiveData from room to ViewModel
// takes requests from ViewModel
// This class is not necessary but recommended , it provides an abstraction between the db and vm
// Repo can grab data from the SQLite db or an internet resource
// REPO can make API calls
// The viewModel calls methods from the repo directly
// The repo calls methods from the DAO
public class WhatEverUserRepo {
private static final String TAG = "MainActivity";
private WhatEverUserDAO whatEverUserDao;
private LiveData userName;
private LiveData userPassword;
public WhatEverUserRepo(Application application){
WhatEverUserDB database = WhatEverUserDB.getDatabase(application);
whatEverUserDao = database.whatEverUserDAO();
//userName = whatEverUserDao.getUsername();
}
public void setUserName(LiveData whatEverUserName){
userName = whatEverUserName;
}
public void getUserName(WhatEverUser whatEverUser){
}
public void insertUserName(String userName){
}
public void getUserEmail(String whatEverUserEmail){
}
public void insertUserEmail(String whatEverUserEmail){
}
public void insertUserPassword(String userPassword){
}
/* public LiveData<String> getUserName() {
return userName;
}*/
// we will need to copy this method and use it in each public method above for each action
private static class getUserAsyncTask extends AsyncTask<WhatEverUser,Void, Void> {
private WhatEverUserDAO wUserDAO ;
private WhatEverUser whatEverUser;
private getUserAsyncTask(WhatEverUser whatEverUser){
this.wUserDAO = wUserDAO;
}
@Override
protected Void doInBackground(WhatEverUser... whatEverUser) {
//wUserDAO.getUsername();
return null;
}
}
public void startThread(View view){
for (int i = 0; i < 10; i++){
Log.d(TAG,"startThread: " + i);
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public void stopThread(View view){
}
}
视图模型
package com.example.whatever.viewModels;
import android.app.Application;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.whatever.db.WhatEverUser;
import com.example.whatever.repositories.WhatEverUserRepo;
public class ViewModelEmailLogin extends AndroidViewModel {
private static final String TAG = "WhatEverLogState";
private WhatEverUserRepo whatEverUserRepo;
private MutableLiveData<WhatEverUser> whatEverUser;
private MutableLiveData<CharSequence> UserName = new MutableLiveData<>();
private MutableLiveData<CharSequence> uPassword = new MutableLiveData<>();
private MutableLiveData<CharSequence> UserEmail = new MutableLiveData<>();
private MutableLiveData<WhatEverUser> WhatEverUser = new MutableLiveData<>();
public ViewModelEmailLogin(@NonNull Application application) {
super(application);
Log.i(TAG, "Instanced");
whatEverUserRepo = new WhatEverUserRepo(application);
Log.i(TAG, "Set whatEverUserRepo");
LiveData<WhatEverUser> whatEverUserLiveData; // not sure what this is for
LiveData<CharSequence>UserEmail;
LiveData<CharSequence>UserPassword;
}
}
还有grad尔
apply plugin: 'com.android.application'
//apply plugin: 'kotlin-android'
//apply plugin: 'kotlin-kapt'
//apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.whatever"
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures{
dataBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
def lifecycle_version = '2.2.0'
def room_version = '2.2.5'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation "com.google.android.material:material:1.1.0"
implementation 'androidx.cardview:cardview'
implementation 'androidx.recyclerview:recyclerview'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation 'com.twitter.sdk.android:twitter:3.1.1'
implementation 'com.twitter.sdk.android:twitter-core:3.1.1'
//lifecycle components
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Room Components
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.core:core-ktx:+"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//kapt "androidx.arch.persistence.room:compiler$room_version"
// kapt "androidx.room:room-compiler:2.2.5"
}
repositories {
mavenCentral()
}
1条答案
按热度按时间f0brbegy1#
如文件室设置说明所示,生成依赖项必须包括:
"annotationProcessor "androidx.room:room-compiler:$room_version"