I am trying to query some data saved in room local database using the id. I have received the id from a serialized object and passed it to my view model class which calls the repository to perform the query using the dao.
An asynctask is used to make things async and return the requested value from db. I have made an interface and initialized it in the async task so I can return the result from db but it fails with NPE.
In activity, I have called repository and passed the serialized data like:
public class ViewSessionActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = ViewSessionActivity.class.getSimpleName();
private Toolbar toolbar;
private Sessions sessions; // serialized object from adapter
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_session);
init();
setSupportActionBar(toolbar);
}
private void init() {
// skipped fvid calls
sessions = (Sessions) getIntent().getSerializableExtra(Constants.SESSION_DETAIL_KEY);
Log.d(TAG, "Prog id:\t" + sessions.prog_sessionId);
//error occurs here which leads to async task call in repository
SessionsRepository.getRepository(getApplication()).getSessionByID(sessions.prog_sessionId);
}
and in repository:
public class SessionsRepository {
private static final String TAG = SessionsRepository.class.getSimpleName();
private SessionsDAO dao;
private static SessionsRepository repository = null;
private LiveData<List<Sessions>> allSessions;
private MutableLiveData<Boolean> loadingState;
private Context context;
private final SportsDatabase database;
public SessionsRepository(Application application) {
database = SportsDatabase.getInstance(application);
dao = database.sessionsDAO();
allSessions = dao.getAllSessions();
loadingState = new MutableLiveData<>();
context = application.getApplicationContext();
}
public static SessionsRepository getRepository(Application context){
if (repository == null){
repository = new SessionsRepository(context);
}
return repository;
}
public void fetchSessions() {
String coachId = new PrefsUtils(context).getCoachId();
Call<SessionDetails> call = RestClient.getRestInstance().getSessionsService().fetchSessions(coachId);
call.enqueue(new Callback<SessionDetails>() {
@Override
public void onResponse(Call<SessionDetails> call, Response<SessionDetails> response) {
if (response.isSuccessful()) {
loadingState.postValue(false); // remove progress
SessionDetails details = response.body();
List<Sessions> sessions = details.getSessions();
// Log.d(TAG, "N/w sesh size:\t" + sessions.size());
saveSessions(sessions);
}
}
@Override
public void onFailure(Call<SessionDetails> call, Throwable t) {
loadingState.postValue(false);
Toast.makeText(context, "Error Fetching Sessions", Toast.LENGTH_SHORT).show();
}
});
}
private void saveSessions(List<Sessions> sessions) {
new SaveSessionsTask(dao).execute(sessions);
}
// this method which calls the async task
public void getSessionByID(String id){
new FindSessionTask(dao, context).execute(id);
}
public LiveData<List<Sessions>> getSavedSessions() {
return allSessions;
}
public class SaveSessionsTask extends AsyncTask<List<Sessions>, Void, Void> {
private SessionsDAO dao;
public SaveSessionsTask(SessionsDAO dao) {
this.dao = dao;
}
@Override
protected Void doInBackground(List<Sessions>... lists) {
dao.addSessions(lists[0]);
return null;
}
}
public class FindSessionTask extends AsyncTask<String, Void, Sessions>{
private SessionsDAO dao;
private OnSessionResultCallback callback;
public FindSessionTask(SessionsDAO dao, Context context) {
this.dao = dao;
this.callback = (OnSessionResultCallback) context;
}
@Override
protected Sessions doInBackground(String... strings) {
Sessions sessions = dao.getSessionById(strings[0]);
return sessions;
}
@Override
protected void onPostExecute(Sessions sessions) {
super.onPostExecute(sessions);
Log.d(SessionsRepository.TAG, "Session name:\t" + sessions.session_name);
}
}
// need help in returning the session found from db in onpostexecute method
}
dao class:
@Dao
public interface SessionsDAO {
@Insert
void addSessions(List<Sessions> sessions);
@Query("select * from sessions")
LiveData<List<Sessions>> getAllSessions();
@Query("select * from sessions where prog_sessionId = :id")
Sessions getSessionById(String id); // here
}
and interface callback to receive data in async task on post execute method:
public interface OnSessionResultCallback {
void onSessionFound(Sessions sessions);
}
Error in logcat:
Caused by: java.lang.ClassCastException: sashi.in.ecosports.extras.App cannot be cast to sashi.in.ecosports.interfaces.OnSessionResultCallback
at sashi.in.ecosports.rest.db.repositories.SessionsRepository$FindSessionTask.<init>(SessionsRepository.java:110)
at sashi.in.ecosports.rest.db.repositories.SessionsRepository.getSessionByID(SessionsRepository.java:82)
at sashi.in.ecosports.ui.activities.ViewSessionActivity.init(ViewSessionActivity.java:63)
at sashi.in.ecosports.ui.activities.ViewSessionActivity.onCreate(ViewSessionActivity.java:38)
at android.app.Activity.performCreate(Activity.java:6671)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
....
I was expecting to log out the found session name but instead got NPE. Can someone help me out in executing a room query async, using an entity field as search string to return the entire entity from a list. How does the view model receive the data and is my interface necessary? Thanks.
NullPointerExceptionbut in your attached logcat I'm seeingClassCastException. Have you attached it right? - Sdghasemithis.callback = (OnSessionResultCallback) context;.contextis application context but it should be a callback. - Leonardo Velozo