【问题标题】:unable to retrieve data of a single row using room database [duplicate]无法使用房间数据库检索单行数据[重复]
【发布时间】:2019-07-12 07:01:21
【问题描述】:

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

我的输出是:

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>>

任何可行的例子都会很棒!

谢谢

【问题讨论】:

标签: java android nullpointerexception android-room android-mvvm


【解决方案1】:

问题是您将 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。

您应该更改原始笔记实时数据中的值,而不是更改参考。

看起来像 -

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));  
}

【讨论】:

  • public static void asyncFinished(LiveData results) { note.setValue(results.getValue); // 虽然不是首选方式,但它会帮助您理解为什么您当前的实现不起作用。我不在 Note 类中创建 setValue 方法
  • 注意是livedata对象的引用-private LiveData&lt;Note&gt; note;
  • 我应该在 Note 类中创建 getValue 和 setValue 类
  • setValue 是 LiveData 提供的方法。
猜你喜欢
  • 2019-05-01
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多