首页 > 解决方案 > 无法使用房间数据库检索单行数据

问题描述

无法从获取此输出的数据库中获取特定记录。

我的输出是:

java.lang.RuntimeException:无法启动活动 ComponentInfo{appwork.com.example/appwork.com.example.MainActivity}:java.lang.NullPointerException:尝试调用虚拟方法'void android.arch.lifecycle.LiveData.observe( android.arch.lifecycle.LifecycleOwner, android.arch.lifecycle.Observer)' 在空对象引用上

我正在使用房间数据库、模型视图、存储库和 Dao 文件来获取实时数据,但无法通过以下内容从数据库中获取特定记录

    <pre><code>
    public class MainActivity extends AppCompatActivity {

        private NoteViewModel noteViewModel;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            noteViewModel = 
    ViewModelProviders.of(this).get(NoteViewModel.class);
            noteViewModel.getNote("test7").observe(this, new Observer<Note>()
            {
                   @Override
                   public void onChanged(@Nullable Note note)
                   {
                       Toast.makeText(MainActivity.this,
                            "found title is : " +note.getTitle(),
                            Toast.LENGTH_LONG).show();
                   }
                 });
            }
        }   

    public class NoteViewModel extends AndroidViewModel
    {
        private LiveData<Note> note;

        public NoteViewModel(@NonNull Application application)
        {
            super(application);
    //        note = repository.getNote("");
        }

        public LiveData<Note> getNote(String search)
        {
            repository.getNote(search);
            if(note != null)
            {
                return note;
            }
            return null;
        }
    }


    public class NoteRepository {

        private NoteDao noteDao;
        private LiveData<Note> note;

        public NoteRepository(Application application)
        {
            NoteDatabase noteDatabase = 
    NoteDatabase.getInstance(application);
            noteDao = noteDatabase.noteDao();
        }

        public LiveData<Note> getNote(String search)
        {
            new SearchNoteAsyncTask(noteDao).execute(search);
            if(note != null)
            {
                return note;
            }
            return null;
        }


       public static void asyncFinished(LiveData<Note> results)
       {
            note = results;
       }

        public static class SearchNoteAsyncTask extends AsyncTask<String, Void, LiveData<Note>>
        {
            private NoteDao noteDao;
            private LiveData<Note> note;

            private SearchNoteAsyncTask(NoteDao noteDao)
            {
                this.noteDao = noteDao;
            } 

            public LiveData<Note> doInBackground(String... search)
            {
                return noteDao.getNote(search[0]);
            }

            public void onPostExecute(LiveData<Note> result)
            {
                asyncFinished(result);            
            }
        }
    }

    @Dao
    public interface NoteDao{
    @Query("Select * from note_table where title =:search Order By priority DESC")
        LiveData<Note> getNote(String search);
    }

我在存储库调用中得到响应,但无法从公众那里获得价值

static class SearchNoteAsyncTask extends AsyncTask<String, Void, LiveData<Note>>

任何工作示例都会很棒!

谢谢

标签: javaandroidnullpointerexceptionandroid-roomandroid-mvvm

解决方案


问题是您将 Livedata 的不同引用返回到您的视图中 -

public LiveData<Note> getNote(String search){
    repository.getNote(search);
    if(note != null)
    {
        return note; // this is the livedata reference that UI is observing
    }
    return null;
}

当您从 repo 获得响应时,您会更改 livedata 的引用 -

public static void asyncFinished(LiveData<Note> results) {
    note = results;
}

但是您的 UI 正在收听以前的 LiveData。

您应该更改原始注释 livedata 中的值,而不是更改参考。

那看起来像 -

public static void asyncFinished(LiveData<Note> results) {
    note.setValue(results.getValue); // not the preferred way though, but it will help you understand why your current implementation doesn't work.
}

最好是在原始实时数据上使用转换 -

public LiveData<Note> getNote(String search){
   return Transformations.map(repository.getNote(search), 
          value -> note.setValue(value));  
}

推荐阅读