Я пишу приложение Medicine Reminder, в котором сущность лекарства хранится в базе данных с использованием Room API.Поток приложения выглядит так:
1) Активность с DrawerLayout, поэтому она состоит из NavigationView для Drawer и LinearView для панели инструментов и фрагмента.
2) Фрагмент # 1 (TopFragment - это ListFragment) - есть два варианта.Нажмите на первый элемент, чтобы перейти ко второму фрагменту - MedicineListFragment.
3) MedicineListFragment извлекает все лекарства из БД и отображает их с помощью RecyclerView - все работает.
4) Нажатие на элемент - вэлемент представления переработчика - следует создать намерение, которое создает новое действие MedicineDetailsActivity.Идентификатор медицины выбранного элемента передается намерению в реализации RecylcerViewAdapter.
@Override
public void onBindViewHolder(@NonNull MedicineRecyclerViewAdapter.ViewHolder holder, final int position) {
final Medicine item = medicines.get(position);
holder.itemNameView.setText(item.getName());
holder.itemDescriptionView.setText(item.getDescription());
holder.itemContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, MedicineDetailsActivity.class);
intent.putExtra(MedicineDetailsActivity.EXTRA_MEDICINE, item.getId());
context.startActivity(intent);
}
});
}
5) Следующим шагом должно быть отображение сведений о лекарстве, но подписка на Observer из ViewModel возвращает ноль вместо одного лекарства.Что странно, если я отлаживаю и устанавливаю точку останова перед вызовом метода .observer, лекарство возвращается!
public class MedicineViewModel extends AndroidViewModel {
private AppDatabase db;
public MedicineViewModel(Application application) {
super(application);
createDb();
}
public LiveData<List<Medicine>> findAllBooks() {
return db.medicineModel().findAllMedicine();
}
public LiveData<Medicine> findMedicineById(int id) {
return db.medicineModel().findMedicineById(id);
}
private void createDb() {
db = AppDatabase.getInMemoryDatabase(this.getApplication());
DatabaseInitializer.populateAsync(db);
}
}
И это MedicineDetailsActivity
public class MedicineDetailsActivity extends AppCompatActivity {
public static final String EXTRA_MEDICINE = "EXTRA_MEDICINE";
private MedicineViewModel medicineViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_medicine_details);
medicineViewModel = ViewModelProviders.of(this).get(MedicineViewModel.class);
subscribeMedicine();
}
private void subscribeMedicine() {
Intent intent = getIntent();
int medicineId = intent.getExtras().getInt(EXTRA_MEDICINE);
medicineViewModel.findMedicineById(medicineId).observe(this, new Observer<Medicine>() {
@Override
public void onChanged(@NonNull Medicine medicine) {
showUI(medicine);
}
});
}
private void showUI(Medicine medicine) {
TextView medicineName = findViewById(R.id.medicine_details_name);
medicineName.setText(medicine.getName());
TextView medicineDescription = findViewById(R.id.medicine_details_description);
medicineDescription.setText(medicine.getDescription());
}
}
05-26 09:10:20.258 9482-9482/com.project.medicinereminder I/System.out: Sending WAIT chunk
05-26 09:10:21.282 9482-9489/com.project.medicinereminder I/art: Debugger is active
05-26 09:10:21.460 9482-9482/com.project.medicinereminder I/System.out: Debugger has connected waiting for debugger to settle...
05-26 09:10:21.661 9482-9482/com.project.medicinereminder I/System.out: waiting for debugger to settle...
05-26 09:10:21.863 9482-9482/com.project.medicinereminder I/System.out: waiting for debugger to settle...
05-26 09:10:22.064 9482-9482/com.project.medicinereminder I/System.out: waiting for debugger to settle...
05-26 09:10:22.265 9482-9482/com.project.medicinereminder I/System.out: waiting for debugger to settle...
05-26 09:10:22.465 9482-9482/com.project.medicinereminder I/System.out: waiting for debugger to settle...
05-26 09:10:22.666 9482-9482/com.project.medicinereminder I/System.out:waiting for debugger to settle...
05-26 09:10:22.866 9482-9482/com.project.medicinereminder I/System.out: debugger has settled (1492)
05-26 09:10:23.395 9482-9482/com.project.medicinereminder W/System: ClassLoader referenced unknown path: /data/app/com.project.medicinereminder-1/lib/arm64
05-26 09:10:23.416 9482-9482/com.project.medicinereminder I/InstantRun: starting instant run server: is main process
05-26 09:10:23.463 9482-9482/com.project.medicinereminder I/HwCust: Constructor found for class android.app.HwCustActivityImpl
05-26 09:10:23.524 9482-9482/com.project.medicinereminder W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
05-26 09:10:23.826 9482-9482/com.project.medicinereminder I/HwSecImmHelper: mSecurityInputMethodService is null
05-26 09:10:23.832 9482-9482/com.project.medicinereminder I/HwPointEventFilter: do not support AFT because of no config
05-26 09:10:23.892 9482-9511/com.project.medicinereminder I/OpenGLRenderer: Initialized EGL, version 1.4
05-26 09:10:23.902 9482-9511/com.project.medicinereminder W/linker: /vendor/lib64/libhwuibp.so: unused DT entry: type 0xf arg 0xe3a
05-26 09:10:24.002 9482-9482/com.project.medicinereminder W/art: Before Android 4.1, method int android.support.v7.widget.DropDownListView.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
05-26 09:10:24.253 9482-9487/com.project.medicinereminder I/art: Do partial code cache collection, code=29KB, data=29KB
05-26 09:10:24.254 9482-9487/com.project.medicinereminder I/art: After code cache collection, code=29KB, data=29KB Increasing code cache capacity to 128KB
05-26 09:10:33.236 9482-9482/com.project.medicinereminder I/hwaps: JNI_OnLoad
05-26 09:10:33.559 9482-9487/com.project.medicinereminder I/art: Do partial code cache collection, code=51KB, data=56KB
05-26 09:10:33.560 9482-9487/com.project.medicinereminder I/art: After code cache collection, code=50KB, data=55KB Increasing code cache capacity to 256KB
05-26 09:10:33.750 9482-9487/com.project.medicinereminder I/art: Compiler allocated 7MB to compile void android.widget.TextView.<init> (android.content.Context, android.util.AttributeSet, int, int)
05-26 09:10:47.687 9482-9489/com.project.medicinereminder I/art: Starting a blocking GC Instrumentation
05-26 09:10:47.728 9482-9487/com.project.medicinereminder I/art: Do full code cache collection, code=123KB, data=118KB
05-26 09:10:47.729 9482-9487/com.project.medicinereminder I/art: After code cache collection, code=120KB, data=92KB
05-26 09:10:47.783 9482-9482/com.project.medicinereminder I/HwPointEventFilter: do not support AFT because of no config
05-26 09:10:49.733 9482-9482/com.project.medicinereminder E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.project.medicinereminder, PID: 9482
java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.project.medicinereminder.database.Medicine.name' on a null object reference
at com.project.medicinereminder.MedicineDetailsActivity.showUI(MedicineDetailsActivity.java:44)
at com.project.medicinereminder.MedicineDetailsActivity.access$000(MedicineDetailsActivity.java:16)
at com.project.medicinereminder.MedicineDetailsActivity$1.onChanged(MedicineDetailsActivity.java:37)
at com.project.medicinereminder.MedicineDetailsActivity$1.onChanged(MedicineDetailsActivity.java:34)
at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
at android.arch.lifecycle.LiveData$1.run(LiveData.java:87)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6623)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
05-26 09:10:49.749 9482-9482/com.project.medicinereminder I/Process: Sending signal. PID: 9482 SIG: 9
Я могу, конечно, поставить Parcerable или Serializable на намерение (я пробовал со вторым - он работает), но я хочу сделать это, используя вышеупомянутый способ.Пожалуйста, помогите!