I have an app where a user can create/login an account, when the user logs in, I pass their valid email as an intent to the main/landing activity .
I also have another activity for the user profile, from which I pass the intent from the landing activity (the user email).
With the user email I created queries to get all the user projects (it's a PM tool kind of thing) - in my landing activity i have a fragment also where I use these queries based on the user email.
In my user profile activity i also created queries to get the users details (name, email etc) to show in their profile where they can change it etc.
========
The issue is, initially when I log in with valid details and I'm brought to the landing activity, I get the users projects which is great, I can also navigate to the users profile activity and I get the users details which is what I want.
Then when I move back to the landing activity my intent (users emaill) which was passed from the Login activity is no longer valid, so I do not get any results from my DB queries and when I move back to the profile activity the intent is null so i can't get the current user anymore.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.ppmtoolmobile.model.User.getFirstName()' on a null object reference
I wanted some advice on how to handle this to avoid getting NPE when moving back and forth.
I removed the variables for components to make it more readable, but I have initialized them all etc..
Landing Activity / ProjectActivity.java
public class ProjectActivity extends AppCompatActivity implements View.OnClickListener, MyRecyclerAdapter.OnProjectClickListener {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_project);
// My dao implementation with DB queries
daoHelper = new DaoHelper(this);
// getting current username through intent from LoginActivity.class
authenticatedUser = getIntent().getStringExtra("authenticatedUser");
Toast.makeText(this, "project activity: " authenticatedUser, Toast.LENGTH_SHORT).show();
// current user id
userId = daoHelper.getCurrentUserId(authenticatedUser);
// Getting users first name and amount of projects (This will be displayed in the heading of the main screen)
userFirstName = daoHelper.getCurrentUserFirstName(authenticatedUser);
projectCount = daoHelper.getProjectCount(userId);
welcomeUserTextView1.setText("Welcome " userFirstName ", " userId);
displayUserProjectCountTextView.setText("You currently have " projectCount " projects");
loadFragment(new ProjectFragment());
// Perform item selected listener
bottomNavView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.nav_profile:
Intent goToProfileActivityIntent = new Intent(ProjectActivity.this, ProfileActivity.class);
goToProfileActivityIntent.putExtra("authenticatedUser", authenticatedUser);
startActivity(goToProfileActivityIntent);
overridePendingTransition(0,0);
return true;
case R.id.nav_home:
return true;
case R.id.nav_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
}
ProfileActivity.java
public class ProfileActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
// getting current username through intent from ProjectActivity.class
authenticatedUser = getIntent().getStringExtra("authenticatedUser");
Toast.makeText(this, "profile activity: " authenticatedUser, Toast.LENGTH_SHORT).show();
daoHelper = new DaoHelper(this);
loadUserDetails();
// Perform item selected listener
bottomNavView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.nav_home:
startActivity(new Intent(getApplicationContext(), ProjectActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.nav_profile:
return true;
case R.id.nav_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
private void loadUserDetails() {
// I get NPE here when moving from ProjectActivity for the second time
User user = daoHelper.getUserDetails(authenticatedUser);
profileFirstNameEditText.setText(user.getFirstName());
profileLastNameEditText.setText(user.getLastName());
profileEmailAddressEditText.setText(user.getEmailAddress());
}
}
DaoHelper.java methods
// get user details
public User getUserDetails(String theEmailAddress) {
SQLiteDatabase db = this.getReadableDatabase();
User user = null;
Cursor cursor = db.query(USER_TABLE,// Selecting Table
new String[]{COLUMN_USER_ID, COLUMN_USER_FIRST_NAME, COLUMN_USER_LAST_NAME, COLUMN_USER_EMAIL_ADDRESS, COLUMN_USER_PASSWORD},//Selecting columns want to query
COLUMN_USER_EMAIL_ADDRESS " = ?",
new String[]{String.valueOf(theEmailAddress)},//Where clause
null, null, null);
System.out.println("cursor count: " cursor.getCount());
if(cursor.moveToNext()) {
long userId = cursor.getLong(0);
String firstName = cursor.getString(1);
String lastName = cursor.getString(2);
String emailAddress = cursor.getString(3);
String password = cursor.getString(4);
user = new User(userId, firstName, lastName, emailAddress, password);
}
return user;
}
// get project count of user
public int getProjectCount(long userId) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " PROJECT_TABLE " WHERE " COLUMN_USER_PROJECT_FK " = ?", new String[]{String.valueOf(userId)})
return cursor.getCount();
}
// get all of users projects
@RequiresApi(api = Build.VERSION_CODES.O)
public List<Project> getUserProjects(long userId) {
SQLiteDatabase db = this.getReadableDatabase();
List<Project> projectList = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM " PROJECT_TABLE " WHERE " COLUMN_USER_PROJECT_FK " = ?", new String[]{String.valueOf(userId)});
while(cursor.moveToNext()) {
long id = cursor.getLong(0);
String title = cursor.getString(1);
String description = cursor.getString(2);
String dateCreated = cursor.getString(3);
String dateDue = cursor.getString(4);
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime dateCreatedFormatted = LocalDateTime.parse(dateCreated, formatter);
LocalDateTime dateDueFormatted = LocalDateTime.parse(dateDue, formatter);
String priority = cursor.getString(5);
String checklist = cursor.getString(6);
int theUserId = cursor.getInt(7);
Project project = new Project(id, title, description, dateCreatedFormatted, dateDueFormatted, priority, checklist, theUserId);
projectList.add(project);
}
return projectList;
}
CodePudding user response:
The problem here is, your are starting another ProjectActivity instance in your ProfileActivity's onNavigationItemSelected listener of bottomNavView, which has no arguments (startActivity(new Intent(getApplicationContext(), ProjectActivity.class));
)
That's why in your second instance of ProjectActivity, it has no value for parameter authenticatedUser and returning empty string.
You can fix this by modifying code of bottomNavView's onNavigationItemSelected listener in your ProfileActivity class.
Replace your switch case logic for id R.id.nav_home like below in ProfileActivity class
case R.id.nav_home:
finish();
overridePendingTransition(0,0);
return true;
Or, if you want to keep multiple instance of same activity (ProjectActivity and ProfileActivity), then you can add parameter to Intent instance in ProfileActivity's bottomNavView's itemSelectedListener. In that case, your code would become something like below
case R.id.nav_home:
Intent goToProjectActivity = new Intent(ProfileActivity.this, ProjectActivity.class);
goToProjectActivity.putExtra("authenticatedUser", authenticatedUser);
startActivity(goToProjectActivity);
overridePendingTransition(0,0);
return true;