【发布时间】:2021-05-31 18:17:13
【问题描述】:
我正在我的活动中创建一个视图模型,以便通过方法将对象添加到数据库中。但是视图模型表示的是一个空表,它导致了这个堆栈跟踪和应用程序的完全崩溃:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gmproxy.pastilarma, PID: 9827
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gmproxy.pastilarma/com.gmproxy.pastilarma.UserAddScreen}: java.lang.RuntimeException: Cannot create an instance of class com.gmproxy.Util.PathologyUserViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.gmproxy.Util.PathologyUserViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:275)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.gmproxy.pastilarma.UserAddScreen.onCreate(UserAddScreen.java:84)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.gmproxy.pastilarma.UserAddScreen.onCreate(UserAddScreen.java:84)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:385)
at androidx.room.RoomDatabase.query(RoomDatabase.java:441)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at com.gmproxy.DAO.PathologyUserDAO_Impl.getAllObjects(PathologyUserDAO_Impl.java:154)
at com.gmproxy.DAO.PathologyUserRepository.getAllObjects(PathologyUserRepository.java:19)
at com.gmproxy.Util.PathologyUserViewModel.<init>(PathologyUserViewModel.java:19)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.gmproxy.pastilarma.UserAddScreen.onCreate(UserAddScreen.java:84)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我一进入所述活动就会发生这种情况。在数据库中有记录的其他视图模型创建没有问题,但是在数据库中缺少任何对象的其他视图模型也无法创建。我是否故意需要添加记录才能创建这些记录?
这分别是activity和view model的代码:
活动:
package com.gmproxy.pastilarma;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.lifecycle.ViewModelProvider;
import com.gmproxy.DAO.PathologyUserDAO;
import com.gmproxy.DAO.UserDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import com.gmproxy.Util.AlarmUserViewModel;
import com.gmproxy.Util.ImageConverter;
import com.gmproxy.Util.PathologyUserViewModel;
import com.gmproxy.Util.UserViewModel;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class UserAddScreen extends AppCompatActivity {
Button gotoBack, addObservation, saveUser, addPathologies;
EditText addUsername, addSurname, addAge, addRoomNumber;
Spinner addGender;
ImageView selectImage;
String obs;
Pathology paths;
Context context;
UserViewModel userViewModel;
PathologyUserViewModel pathologyUserViewModel;
int pathAct = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
Intent intent = this.getIntent();
context = this.getApplicationContext();
Bundle bundle = new Bundle();
pathAct = getIntent().getIntExtra("path-record",0);
if (pathAct == 1){
onRestoreInstanceState(bundle);
}
setContentView(R.layout.activity_user_add_screen);
gotoBack = findViewById(R.id.GotoBack);
addObservation = findViewById(R.id.AddObservation);
saveUser = findViewById(R.id.SaveUser);
addPathologies = findViewById(R.id.AddPathologies);
addUsername = findViewById(R.id.AddUsername);
addSurname = findViewById(R.id.AddSurname);
addAge = findViewById(R.id.AddAge);
addRoomNumber = findViewById(R.id.AddRoomNumber);
addGender = findViewById(R.id.AddGender);
selectImage = findViewById(R.id.SelectImage);
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
pathologyUserViewModel = new ViewModelProvider(this).get(PathologyUserViewModel.class);
List<String> genderList = new ArrayList<>();
genderList.add("M");
genderList.add("F");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,genderList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
addGender.setAdapter(adapter);
obs = intent.getStringExtra("observation");
paths = (Pathology) intent.getSerializableExtra("paths");
}
public void gotoBack(View view) {
Intent mainAct = new Intent(UserAddScreen.this, UserListScreen.class);
startActivity(mainAct);
}
public void addObservation(View view) {
Intent mainAct = new Intent(UserAddScreen.this, UserObservationScreen.class);
startActivity(mainAct);
}
public void addPathology(View view) {
Intent mainAct = new Intent(UserAddScreen.this, PathologiesSearchScreen.class);
startActivity(mainAct);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("Nombre_usuario",addUsername.getText().toString());
savedInstanceState.putString("Apellido_usuario",addSurname.getText().toString());
savedInstanceState.putString("Edad_usuario",addAge.getText().toString());
savedInstanceState.putString("Habitacion_usuario",addRoomNumber.getText().toString());
savedInstanceState.putInt("Sexo_usuario",addGender.getSelectedItemPosition());
savedInstanceState.putString("Observacion-usuario", obs);
savedInstanceState.putSerializable("Patologia-usuario", paths);
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
addUsername.setText(savedInstanceState.getString("Nombre_usuario"));
addSurname.setText(savedInstanceState.getString("Apellido_usuario"));
addAge.setText(savedInstanceState.getString("Edad_usuario"));
addRoomNumber.setText(savedInstanceState.getString("Habitacion_usuario"));
addGender.setSelection(savedInstanceState.getInt("Sexo_usuario"));
obs = savedInstanceState.getString("Observacion-usuario");
paths = (Pathology) savedInstanceState.getSerializable("Patologia-usuario");
}
public void selectImageAction(View view) {
final CharSequence[] options = {"Hacer una foto", "Elegir de la galería", "Usar una genérica" , "Cancelar"};
AlertDialog.Builder builder = new AlertDialog.Builder(UserAddScreen.this);
builder.setTitle("¡Añade una foto!");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Hacer una foto")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivity(intent);
} else if (options[item].equals("Elegir de la galería")) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivity(intent);
} else if (options[item].equals("Cancelar")) {
dialog.dismiss();
} else if(options[item].equals("Usar una genérica")){
selectImage.setImageResource(R.drawable.ic_user_generic_foreground);
selectImage.setBackgroundResource(R.drawable.ic_user_generic_foreground);
}
}
});
builder.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);
selectImage.setImageBitmap(bitmap);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == 2) {
Uri selectedImage = data.getData();
String[] filePath = {MediaStore.Images.Media.DATA};
Cursor c = getContentResolver().query(selectedImage, filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Log.w("..******************...", picturePath + "");
ImageView viewImage;
selectImage.setImageBitmap(thumbnail);
}
}
}
public void saveUser(View view) {
//Just this to turn the image into a blob
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.id.SelectImage);
ImageConverter imgCon = new ImageConverter();
byte[] bytearray = imgCon.bitmapToBiteArray(bitmap);
Toast.makeText(this, "Usuario creado.", Toast.LENGTH_SHORT).show();
User user = new User(addUsername.getText().toString(), addSurname.getText().toString(), addAge.getText().toString(),
Integer.parseInt(addRoomNumber.getText().toString()), addGender.getSelectedItem().toString(), obs, bytearray);
userViewModel.insert(user);
pathologyUserViewModel.insert(userViewModel.getIdByNameAndSurname(addUsername.getText().toString(),addSurname.getText().toString()), paths.getId_pathology());
Toast.makeText(this, "Patología " + paths.getPathologyName() + " añadida", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(UserAddScreen.this, UserListScreen.class);
startActivity(mainAct);
finish();
}
}
查看模型:
package com.gmproxy.Util;
import android.app.Application;
import androidx.lifecycle.AndroidViewModel;
import com.gmproxy.DAO.PathologyUserRepository;
import com.gmproxy.Entities.PathologyUser;
import java.util.List;
public class PathologyUserViewModel extends AndroidViewModel {
private PathologyUserRepository repository;
public List<PathologyUser> pathologyUsers;
public PathologyUserViewModel(Application application) {
super(application);
repository = new PathologyUserRepository(application);
pathologyUsers = repository.getAllObjects();
}
List<PathologyUser> getAll() { return pathologyUsers; }
public List<PathologyUser> getAllFromUser(int i) { return repository.getAllFromUser(i); }
public void insert(int i, int j) { repository.insertObject(i,j); }
public void delete(PathologyUser obj) { repository.deleteObject(obj); }
}
我不太记得在文档中无法使用空表创建视图模型的任何内容,也许我遗漏了什么?
【问题讨论】:
-
您的崩溃表明错误在
com.gmproxy.pastilarma.UserAddScreen.onRestoreInstanceState(UserAddScreen.java:125);这与您的 ViewModel 无关。你能包括你的UserAddScreen吗? -
这是在视图模型上编码的活动。是的,忘记了一件非常重要的事情,现在会解决它,给我一分钟
标签: java android android-room viewmodel