List<> from Room Database is always null - android

The following classes are used to store a list of surveys in a Room database. LiveData is used to be able to update
Entity class for Database:
#Entity
public class Survey {
#PrimaryKey
#NonNull
private String surveyID;
private String surveyName;
private String url;
private double lat;
private double lng;
private double radius;
public Survey(String surveyID, String surveyName, double lat, double lng, double radius, String url) {
this.surveyID = surveyID;
this.surveyName = surveyName;
this.lat = lat;
this.lng = lng;
this.radius = radius;
this.url = url;
}
Respective Dao Interface:
#Dao
public interface SurveyDao {
#Query("SELECT * FROM Survey")
LiveData<List<Survey>> getListOfSurveys();
/* Rest omitted */
}
Respective Repository class
public class SurveyRepository {
private final SurveyDao surveyDao;
#Inject
public SurveyRepository (SurveyDao surveyDao){
this.surveyDao = surveyDao;
}
public LiveData<List<Survey>> getListOfSurveys(){
return surveyDao.getListOfSurveys();
}
/* Rest omitted */
}
ViewModel:
public class SurveyCollectionViewModule extends ViewModel {
private SurveyRepository repository;
public SurveyCollectionViewModule(SurveyRepository repository) {
this.repository = repository;
}
public LiveData<List<Survey>> getSurveys(){
return repository.getListOfSurveys();
}
/* Rest Omitted */
}
Using all of this, I have setup a Fragment which has a RecyclerView displaying the list of surveys. The list is obtained in the following way:
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
surveyCollectionViewModule = ViewModelProviders.of(this, viewModelFactory)
.get(SurveyCollectionViewModule.class);
surveyCollectionViewModule.getSurveys().observe(this, new Observer<List<Survey>>() {
#Override
public void onChanged(#Nullable List<Survey> surveys) {
if(SurveyListFragment.this.listOfSurveys == null) {
setSurveyData(listOfSurveys);
}
}
});
}
However, I am running into the problem, where the call to getItemCount() in the adapter fails due to this list being NULL. The database does not contain any entries but I am still at a lost as to why the list is always returning as null.

Your onChanged doesn't actually use the surveys parameter it is given, change it to call setSurveyData(surveys) to actually fill out your data.

make some changes in ViewModel class like below ...
private final LiveData<List<Survey>> SurveyList;
private AppDatabase appDatabase;
public SurveyCollectionViewModule(Application application) {
appDatabase = AppDatabase.getDatabase(this.getApplication());
SurveyList = appDatabase.surveyDao().getAllSurvey();
}
public LiveData<List<Survey>> getSurveys() {
return SurveyList;
}

Related

json array is not available in my response, i am trying to save my response in model class using retrofit

i am trying to get the response using retrofit but problem is that there is no Json Array in my response. how can we get data?
{
"BTC": {
"USD": 7183.56
},
"ETH": {
"USD": 183.3
}
}
i am trying the code. which looks like this,
#GET("/urlpath")
Call<currency> getAllCurrency( Query("api-key") String api-key );
And i am using this pojo class;
public class currency {
/**
* BTC : {"USD":7183.56}
*/
private BTCBean BTC;
public BTCBean getBTC() {
return BTC;
}
public void setBTC(BTCBean BTC) {
this.BTC = BTC;
}
public static class BTCBean {
/**
* USD : 7183.56
*/
private double USD;
public double getUSD() {
return USD;
}
public void setUSD(double USD) {
this.USD = USD;
}
}
}
This might be useful to you. I have used the RoboPOJOGenerator plugin to generate models from your given response.
data class ResponseModel(
#field:SerializedName("BTC")
val bTC: BTC? = null,
#field:SerializedName("ETH")
val eTH: ETH? = null
)
data class BTC(
#field:SerializedName("USD")
val uSD: Double? = null
)
data class ETH(
#field:SerializedName("USD")
val uSD: Double? = null
)
I think your POJO class must have the 2 keys, you are just adding one of the keys which is BTC, try this:
public class currency {
/**
* BTC : {"USD":7183.56}
*/
private BTCBean BTC;
//add this
private BTCBean ETH;
//add all setters and getters for the above 2 fields
//...........
//...........
public static class BTCBean {//keep this as you did it.........}
}
Your Pojo class is like below:
public class Currency{
#SerializedName("BTC")
#Expose
private BTC bTC;
#SerializedName("ETH")
#Expose
private ETH eTH;
public BTC getBTC() {
return bTC;
}
public void setBTC(BTC bTC) {
this.bTC = bTC;
}
public ETH getETH() {
return eTH;
}
public void setETH(ETH eTH) {
this.eTH = eTH;
}
public class ETH {
#SerializedName("USD")
#Expose
private Double uSD;
public Double getUSD() {
return uSD;
}
public void setUSD(Double uSD) {
this.uSD = uSD;
}
}
public class BTC {
#SerializedName("USD")
#Expose
private Double uSD;
public Double getUSD() {
return uSD;
}
public void setUSD(Double uSD) {
this.uSD = uSD;
}
}
}

Populate Room Database with Arraylist

I would like to build a Deckbuilder that allows you to save created decks locally on the device.
The Decklist are stored in Arraylists, called TransferDeck. Which I would like to store in room database. My issue is, that I do not know how to populate my database correctly, with the data comming out of the Arraylist.
I am used to working with Arraylist and below you see my try for storing the data:
So this is what I tried but what sadly does not work:
private void populateDB(final List<TransferDeck> mTransferDeck) {
new Thread(new Runnable() {
#Override
public void run() {
List<SaveDeck> mSaveDeck = new ArrayList<>();
for(int i = 0; i<mTransferDeck.size(); i++){
mSaveDeck.add(new SaveDeck(i, "FirstSavedDeck", mTransferDeck.get(i).getCardImage() ,mTransferDeck.get(i).getTypeImage(), mTransferDeck.get(i).getCost(), mTransferDeck.get(i).getName(), mTransferDeck.get(i).getNumber()));
}
mSavedDecksDB.deckBuilderDao().insertCards(mSaveDeck);
}
}).start();
}
Below you can find the rest of my code, but the above one should be enough to make clear what I want to do...
I created the class SaveDeck which should be able to Save a Deck with a given Deckname:
:-
#Entity
public class SaveDeck implements Serializable {
#PrimaryKey(autoGenerate = true)
private int _id;
public SaveDeck(int _id, String deckName, int cardImage, int typeImage, Integer cardCost, String cardName, Integer cardNumber) {
this._id = _id;
DeckName = deckName;
CardImage = cardImage;
TypeImage = typeImage;
CardCost = cardCost;
CardName = cardName;
CardNumber = cardNumber;
}
#ColumnInfo(name = "DeckName")
private String DeckName;
#ColumnInfo(name = "CardImage")
private int CardImage;
#ColumnInfo(name = "TypeImage")
private int TypeImage;
#ColumnInfo(name = "CardCost")
private Integer CardCost;
#ColumnInfo(name = "CardName")
private String CardName;
#ColumnInfo(name = "CardNumber")
private Integer CardNumber;
}
I created the Dao Class as follows:
:-
#Dao
public interface DeckBuilderDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
public long[] insertCards(SaveDeck... saveDecks);
#Insert(onConflict = OnConflictStrategy.IGNORE)
public long insertCard(SaveDeck saveDecks);
#Update
public int updateCardBaseEntries(SaveDeck... saveDecks);
#Update
public int updateCardBaseEntry(SaveDeck saveDecks);
#Delete
public int deleteCardBaseEntried(SaveDeck... saveDecks);
#Delete
public int deleteCardBaseEntry(SaveDeck saveDecks);
#Query("SELECT * FROM SaveDeck")
public SaveDeck[] getAllDecks();
//probably I do not need the getAllDecks Query. Right now I only need the following one:
#Query("SELECT * FROM SaveDeck WHERE DeckName = :NameOfDeck ORDER BY DeckName, CardName")
public SaveDeck getOneDeck(String NameOfDeck);
}
Furthermore created the DataBase Class:
#Database(entities = {SaveDeck.class}, version = 1)
public abstract class SaveDecksDataBase extends RoomDatabase {
public abstract DeckBuilderDao deckBuilderDao();
}
The last class is a fragment, where I try to populate my database, and in the populateDB() class is the issue
public class review_fragment extends Fragment {
private List<TransferDeck> mTransferDeck = DataHolder.getInstance().savedDecklistTransfer;
SaveDecksDataBase mSavedDecksDB;
Cursor mCursor;
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//return super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.review_fragment, container, false);
/*Introduce Cards Recycler*/
RecyclerView rvCards = view.findViewById(R.id.rv_review_cardlist);
rvCards.setLayoutManager(new GridLayoutManager(getActivity(), 5));
review_RViewAdapter_Cards adapterCards = new review_RViewAdapter_Cards(getContext(), mTransferDeck);
rvCards.setAdapter(adapterCards);
/*Init Room database*/
mSavedDecksDB = Room.databaseBuilder(getActivity(),SaveDecksDataBase.class,"SavedDecksDB.db").build();
populateDB(mTransferDeck);
return view;
}
private void populateDB(final List<TransferDeck> mTransferDeck) {
new Thread(new Runnable() {
#Override
public void run() {
List<SaveDeck> mSaveDeck = new ArrayList<>();
for(int i = 0; i<mTransferDeck.size(); i++){
mSaveDeck.add(new SaveDeck(i, "FirstSavedDeck", mTransferDeck.get(i).getCardImage() ,mTransferDeck.get(i).getTypeImage(), mTransferDeck.get(i).getCost(), mTransferDeck.get(i).getName(), mTransferDeck.get(i).getNumber()));
}
mSavedDecksDB.deckBuilderDao().insertCards(mSaveDeck);
}
}).start();
}
}
I like to mention that this should be a comment rather than an answer.
First, either use AysncTask or use more robust Executors.newSingleThreadExecutor(). If you prefer the second one then it's best if you create a helper class (example). Example:
private void populateDB(final List<TransferDeck> mTransferDeck) {
AppExecutors.diskIO().execute(() -> {
for(int i = 0; i<mTransferDeck.size(); i++){
mSavedDecksDB.deckBuilderDao().insertCards(new SaveDeck(...);
}
});
}
(1) Create a blank constructor.
(4) Room Database should not be initialized there and it's best if it's singleton. So the your database class (3) can be like:
public abstract class SaveDecksDataBase extends RoomDatabase {
private static SaveDecksDataBase sINSTANCE;
private static final Object LOCK = new Object();
public static SaveDecksDataBase getDatabase(final Context context) {
if (sINSTANCE == null) {
synchronized (LOCK) {
if (sINSTANCE == null) {
sINSTANCE = Room.databaseBuilder(context.getApplicationContext(),
SaveDecksDataBase.class, "SavedDecksDB.db")
.build();
}
}
}
return sINSTANCE;
}
public abstract DeckBuilderDao deckBuilderDao();
}
Lastly, to get SaveDeck object you also has to use Executors or AsyncTask to do the work in background, and then populate the RecyclerView.
Android Room Database
Practice set

Insert a list of objects in the local base, Room

I have the CidVo class:
#Entity
public class CidVo implements Serializable {
private static final long serialVersionUID = 6128323407787450445L;
#NonNull
#PrimaryKey
private String idCid;
private String dsCid;
//private StatusType idStatus;
public CidVo() {
super();
}
public String getIdCid() {
return idCid;
}
public void setIdCid(String idCid) {
this.idCid = idCid;
}
public String getDsCid() {
return dsCid;
}
public void setDsCid(String dsCid) {
this.dsCid = dsCid;
}
/*public StatusType getIdStatus() {
return idStatus;
}
public void setIdStatus(StatusType idStatus) {
this.idStatus = idStatus;
} */
}
The DAO class:
#Dao
public interface CIDDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllCID(ArrayList<CidVo>... cidVos);
}
I get a list of objects, via JSON. And I would like to save it in the database.
But, I get this return error when trying to compile:
Error:Entity class must be annotated with #Entity
E:\workspace_android_studio\app_atendimento_branch_test\app\src\main\java\br\com\sisteplan\app\atendimento\Model\CIDDao.java
Error:(19, 43) error: Type of the parameter must be a class annotated
with #Entity or a collection/array of it.
How to solve this question?
The following is the postExecute:
#Override
protected void onPostExecute(AsyncTaskResult<Retorno> respAtestadoVo) {
super.onPostExecute(respAtestadoVo);
if (respAtestadoVo.getExceptionResult() == null) {
RetornoCid retornoCid = (RetornoCid) respAtestadoVo.getResult();
ArrayList<CidVo> cidVos = (ArrayList<CidVo>) retornoCid.getRetorno();
appDataBase.getCidDao().insertAllCID(cidVos);
Toast.makeText(context, "Sucesso", Toast.LENGTH_SHORT).show();
}
}
Instance:
#Database(entities = {CidVo.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {
public abstract CIDDao getCidDao();
private static AppDataBase appDataBase;
public static AppDataBase getInstance(Context context){
if(null == appDataBase){
appDataBase = buildDataBaseInstance(context);
}
return appDataBase;
}
private static AppDataBase buildDataBaseInstance(Context context){
return Room.databaseBuilder(context,
AppDataBase.class,
"app_database")
.allowMainThreadQueries().build();
}
private void cleanUp(){
appDataBase = null;
}
}
The reason is a vararg notation here void insertAllCID(ArrayList<CidVo>... cidVos);
You're trying to insert an array of array lists.
So, just replace it with
void insertAllCID(List<CidVo> cidVos);
Also, it's better to use interfaces over implementations, when you're working with collections. So, you can change this part
RetornoCid retornoCid = (RetornoCid) respAtestadoVo.getResult();
ArrayList<CidVo> cidVos = (ArrayList<CidVo>) retornoCid.getRetorno();
to this
RetornoCid retornoCid = (RetornoCid) respAtestadoVo.getResult();
List<CidVo> cidVos = new ArrayList(retornoCid.getRetorno());

LiveData is not updating its value after first call

I have been beating my head against the wall and I cannot understand why this is happening. I am working with the new Architectural Components for Android and I am having problems updating a LiveData with a List of Objects.
I have two spinners. When i change the option in the first one, The second one must have its content changed. But this last part is not happening.
Can anyone help me?
State.java
#Entity(tableName = "states")
public class State{
#PrimaryKey(autoGenerate = false)
private int id;
private String name;
#ColumnInfo(name = "countryId")
private String CountryId;
#Ignore
private Object geoCenter, geoLimit;
public State(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountryId() {
return CountryId;
}
public void setCountryId(String countryId) {
CountryId = countryId;
}
}
StateDAO
#Dao
public interface StateDao {
#Query("SELECT * FROM states")
LiveData<List<State>> getAllStates();
#Query("SELECT * FROM states WHERE countryId = :countryID")
LiveData<List<State>> getStatesFromCountry(String countryID);
#Query("SELECT COUNT(*) FROM states")
int getNrStates();
#Query("SELECT COUNT(*) FROM states WHERE countryId = :countryID")
int getNrStatesByCountry(String countryID);
#Insert(onConflict = IGNORE)
void insertAll(List<State> states);
#Delete
void delete(State state);
}
StateRepository
#Singleton
public class StatesRepository {
private final WebServices services;
private final StateDao stateDao;
private final Executor executor;
#Inject
public StatesRepository(Executor executor, StateDao stateDao, WebServices services) {
this.services = services;
this.stateDao = stateDao;
this.executor = executor;
}
public LiveData<List<State>> getStates(String token){
refreshStates(token);
return stateDao.getAllStates();
}
public LiveData<List<State>> getStatesFromCountry(String countryID){
return stateDao.getStatesFromCountry(countryID);
}
private void refreshStates(final String token){
executor.execute(() -> {
Log.d("oooooo", stateDao.getNrStates() + "");
if(stateDao.getNrStates() == 0){
try {
Response<List<State>> response = services.getStates("Bearer "+token).execute();
stateDao.insertAll(response.body());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
StateViewModel
public class StatesViewModel extends ViewModel {
private LiveData<List<State>> states;
private StatesRepository repo;
#Inject
public StatesViewModel(StatesRepository repository){
this.repo = repository;
}
public void init(String token){
states = repo.getStates(token);
}
public void getStatesFromCountry(String countryID){
states = repo.getStatesFromCountry(countryID);
}
public LiveData<List<State>> getStates(){
return this.states;
}
}
Fragment
public class EditAddressFragment extends LifecycleFragment implements View.OnClickListener, Injectable{
private Spinner country, city, state, zip_code;
private String token;
private List<Country> countries;
private List<City> cities;
private List<State> states;
#Inject ViewModelFactory viewModelFactory;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.addresses_edit_layout, container, false);
city = view.findViewById(R.id.city);
state = view.findViewById(R.id.state);
country = view.findViewById(R.id.country);
...
countries = new ArrayList<>();
cities = new ArrayList<>();
states = new ArrayList<>();
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
CountrySpinnerAdapter adapter = new CountrySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, countries);
country.setAdapter(adapter);
CitySpinnerAdapter cityAdapter = new CitySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, cities);
city.setAdapter(cityAdapter);
StateSpinnerAdapter stateAdapter = new StateSpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, states);
state.setAdapter(stateAdapter);
CountriesViewModel countriesViewModel = ViewModelProviders.of(this, viewModelFactory).get(CountriesViewModel.class);
countriesViewModel.init(token);
countriesViewModel.getCountries().observe(this, adapter::setValues);
CityViewModel cityViewModel = ViewModelProviders.of(this, viewModelFactory).get(CityViewModel.class);
cityViewModel.init(token);
cityViewModel.getCities().observe(this, cityAdapter::setValues);
StatesViewModel statesViewModel = ViewModelProviders.of(this, viewModelFactory).get(StatesViewModel.class);
statesViewModel.init(token);
statesViewModel.getStates().observe(this, states -> {
Log.d("called", states.toString());
stateAdapter.setValues(states); } );
country.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Country c = (Country) adapterView.getItemAtPosition(i);
Log.d("cd", c.getId());
//states = new ArrayList<State>();
statesViewModel.getStatesFromCountry(c.getId());
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
....
Adapter
public void setValues(List<State> states)
{
this.states = states;
Log.d("s", states.isEmpty()+" "+states.toString());
notifyDataSetChanged();
}
Well, I have reached a solution for this issue and found out how this LiveData things works.
Thanks to #MartinMarconcini for all his help is debugging ;)
So apparently, the observers are linked to the object you first set it up to. You cannot replace the object (by attribution) or otherwise it will not work.
Also, if the value of your variable is going to change then you should use MutableLiveData
So the change necessary were:
1. Change from LiveData to MutableLiveData and pass that MutableLiveData to the repository when you need to update it
public class StatesViewModel extends ViewModel {
private MutableLiveData<List<State>> states; ;;CHANGED
private StatesRepository repo;
#Inject
public StatesViewModel(StatesRepository repository){
this.repo = repository;
}
public void init(String token){
states = repo.getStates(token);
}
public void getStatesFromCountry(String countryID){
repo.getStatesFromCountry(this.states, countryID); ;;CHANGED
}
public LiveData<List<State>> getStates(){
return this.states;
}
}
2. In the repository, update the MutableLiveData using setValue
#Singleton
public class StatesRepository {
private final WebServices services;
private final StateDao stateDao;
private final Executor executor;
#Inject
public StatesRepository(Executor executor, StateDao stateDao, WebServices services) {
this.services = services;
this.stateDao = stateDao;
this.executor = executor;
}
public MutableLiveData<List<State>> getStates(String token){
refreshStates(token);
final MutableLiveData<List<State>> data = new MutableLiveData<>();
data.setValue(stateDao.getAllStates());
return data;
}
;; CHANGED
public void getStatesFromCountry(MutableLiveData states, final String countryID){
states.setValue(stateDao.getStatesFromCountry(countryID));
}
private void refreshStates(final String token){
executor.execute(() -> {
if(stateDao.getNrStates() == 0){
try {
Response<List<State>> response = services.getStates("Bearer "+token).execute();
stateDao.insertAll(response.body());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
3. Changed the DAO to return List instead of LiveData>
#Dao
public interface StateDao {
#Query("SELECT * FROM states")
List<State> getAllStates();
#Query("SELECT * FROM states WHERE ctrId = :countryID")
List<State> getStatesFromCountry(String countryID);
#Query("SELECT COUNT(*) FROM states")
int getNrStates();
#Query("SELECT COUNT(*) FROM states WHERE ctrId = :countryID")
int getNrStatesByCountry(String countryID);
#Insert(onConflict = IGNORE)
void insertAll(List<State> states);
#Delete
void delete(State state);
}
4.Finally allow to perform queries in the main thread
AppModule.java
#Singleton #Provides
AppDatabase provideDb(Application app) {
return Room.databaseBuilder(app, AppDatabase.class,"unitail.db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
}
Dao must be same across all operations.
You use different Dao instance for insert and observe
You should not update the livedata reference once you set it and start observing it.Instead to update the live data with repository you should use the MediatorLiveData.
In your case do the following changes:
private MediatorLiveData<List<State>> states; // change
.....
.....
states.addSource(repo.getStatesFromCountry(countryID), newData -> states.setValue(newData)); //change
Writing an answer for better discussion.
So I have (in Kotlin, sry) a model that is a list of notes (it’s just a sandbox app to play w/all this) and here’s my architecture: I don’t have a Repo, but I have Activity -> ViewModel -> Dao.
So Dao exposes a LiveData<MutableList<Note>>
#Query("SELECT * FROM notes")
fun loadAll(): LiveData<MutableList<Note>>
My ViewModel… exposes it through:
val notesList = database.notesDao().loadAll()
and my Activity (onCreate) does…
viewModel.notesList.observe(this,
Observer<MutableList<Note>> { notes ->
if (notes != null) {
progressBar?.hide()
adapter.setNotesList(notes)
}
})
This works. The adapter is a RecyclerView adapter that does literally nothing but:
fun setNotesList(newList: MutableList<Note>) {
if (notes.isEmpty()) {
notes = newList
notifyItemRangeInserted(0, newList.size)
} else {
val result = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return notes.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return notes[oldItemPosition].id == newList[newItemPosition].id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val (id, title, _, priority) = newList[newItemPosition]
val (id1, title1, _, priority1) = notes[oldItemPosition]
return id == id1
&& priority == priority1
&& title == title1
}
})
notes = newList
result.dispatchUpdatesTo(this)
}
}
If ANY other part of the app modifies that list of notes, the adapter updates automagically. I hope this gives you a playground to try a simple(r?) approach.

Using room persistence when trying to fetch items or insert returns null database

Working with room persistence, when trying to get the database to insert or make select in the items, the error appears:
AppDataBase.getMovieDao()' on a null object reference
The classes related to the process are as follows:
AppDataBase class:
#Database(entities = {Movies.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {
public static final String DB_NAME = "Movies";
private static AppDataBase INSTANCE;
public static AppDataBase getDataBase(Context context){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),AppDataBase.class,DB_NAME).build();
}
return INSTANCE;
}
public abstract MovieDao getMovieDao();
}
Dao Class:
#Dao
public interface MovieDao {
#Insert
void insertAll(Movies movies);
#Update
void updateAll(Movies... notes);
#Query("SELECT * FROM moviestb")
List<Movies> getAll();
#Delete
void deleteAll(Movies... notes);
}
Entity class:
#Entity(tableName = "moviestb")
public class Movies {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "idmovie")
private long id;
#ColumnInfo(name = "titlemovie")
private String titlemovie;
........
}
Searching for the registrations:
public void loadFromDB(){
db.getDataBase(view.getContext());
if(db.getMovieDao().getAll().size() > 0){
adapter.setResults(db.getMovieDao().getAll());
}else{
Toast.makeText(view.getContext(),"Não há filmes cadastrados",Toast.LENGTH_SHORT).show();
view.getActivity().finish();
}
}
Insert:
public View.OnClickListener onSaveClick(final String plot, final String diretor, final String autor,
final String nome, final String tipo, final String ano, final String ator, final String imdb) {
return new View.OnClickListener() {
#Override
public void onClick(View itemView) {
db.getDataBase(view.getContext());
Movies movies = new Movies(nome,plot,imdb,"",ator,ano,tipo,diretor,autor);
new InsertAsyncTask(db).execute(movies);
}
};
}
private class InsertAsyncTask extends AsyncTask<Movies,Void,Void>{
private AppDataBase db;
public InsertAsyncTask(AppDataBase appDataBase) {
db = appDataBase;
}
#Override
protected Void doInBackground(Movies... params) {
db.getMovieDao().insertAll(params[0]);
return null;
}
}
Searching all:
public void loadFromDB(){
db.getDataBase(view.getContext());
if(db.getMovieDao().getAll().size() > 0){
adapter.setResults(db.getMovieDao().getAll());
}else{
Toast.makeText(view.getContext(),"Não há filmes cadastrados",Toast.LENGTH_SHORT).show();
view.getActivity().finish();
}
}
The crash occurs while fetching the database, what am I doing wrong? thank you!
db is null, apparently. Your question does not show where you ever assign it a value.
Please note that getDataBase() is a static method. Perhaps you should have a db=AppDataBase.getDataBase() statement somewhere.

Categories

Resources