I'm trying to get the context in the onCreate() method, to use in my RoomDb repository, but it keeps giving me a NullPointerException.
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.example.csc202assignment.database.TripRepository;
public class TripApplication extends Application {
@Override
public void onCreate(){
super.onCreate();
TripRepository.initialise(this);
}
}
repository
import android.content.Context;
import androidx.lifecycle.LiveData;
import androidx.room.Room;
import java.util.List;
import java.util.UUID;
public class TripRepository {
private static TripRepository INSTANCE = null;
private final String DATABASE_NAME = "trip-database";
private Context context;
private TripRepository(Context context) {
this.context = context;
}
//The NPE
TripDatabase database = Room.databaseBuilder(
context.getApplicationContext(),
TripDatabase.class,DATABASE_NAME).build();
TripDao tripDao = database.tripDao();
void deleteTrips(){
tripDao.deleteTrips();
}
void delete(Trip trip){
tripDao.delete(trip);
}
void insertTrip(Trip trip){
tripDao.insertTrip(trip);
}
void updateTrip(Trip trip){
tripDao.updateTrip(trip);
}
public LiveData<List<Trip>> getAll(){
return tripDao.getAll();
}
LiveData<Trip> getTrip(UUID id){
return tripDao.getTrip(id);
}
public static void initialise(Context context){
if(INSTANCE==null){
INSTANCE = new TripRepository(context);
}
}
public static TripRepository get() throws IllegalStateException {
try {
return INSTANCE;
} catch (IllegalStateException e) {
System.out.println("TripRepository must be initialised");
}
return INSTANCE;
}
}
I've tried to look through other explanations, but I just can't wrap my head around it. I've tried GetApplicationContext, and this. I've seen people saying to call the getApplicationContext at the end of the onCreate() method, but isn't that what I'm doing?
CodePudding user response:
You are trying to initialize the database
field before the context
field. Even though you've put it after the constructor, the initializing code is still executed before the constructor. You should do it like this
private Context context;
private TripDatabase database
private TripRepository(Context context) {
this.context = context;
this.database = Room.databaseBuilder(
context.getApplicationContext(),
TripDatabase.class,DATABASE_NAME).build();
}
CodePudding user response:
In Java, fields are initialized before constructor is executed.
You're initializing context
in your constructor but then trying to use it earlier when initializing the database
field.
One way around it is to move the database
setup in the constructor.