简体   繁体   English

来回移动活动时Android意图返回null

[英]Android intent returning null when moving back and forth of activities

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 .我有一个应用程序,用户可以在其中创建/登录帐户,当用户登录时,我将他们的有效电子邮件作为意图传递给 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.使用用户电子邮件,我创建了查询以获取所有用户项目(这是一种 PM 工具)-在我的登陆活动中,我还有一个片段,我在其中使用基于用户电子邮件的这些查询。

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.然后,当我回到登陆活动时,从登录活动传递的意图(用户电子邮件)不再有效,因此我没有从我的数据库查询中得到任何结果,当我回到个人资料活动时,意图是null 所以我不能再获取当前用户了。

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.我想要一些关于如何处理这个问题的建议,以避免在来回移动时出现 NPE。


I removed the variables for components to make it more readable, but I have initialized them all etc..我删除了组件的变量以使其更具可读性,但我已经将它们全部初始化等等。

Landing Activity / ProjectActivity.java登陆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 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 DaoHelper.java 方法

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



登录后的初始状态 移动到配置文件活动然后返回项目活动时的状态

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)); )这里的问题是,您正在 ProfileActivity 的bottomNavViewonNavigationItemSelected侦听器中启动另一个 ProjectActivity 实例,该侦听器没有参数( 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.这就是为什么在 ProjectActivity 的第二个实例中,参数authenticatedUser没有值并返回空字符串。

You can fix this by modifying code of bottomNavView's onNavigationItemSelected listener in your ProfileActivity class.您可以通过在ProfileActivity类中修改 bottomNavView 的 onNavigationItemSelected 侦听器的代码来解决此问题。 Replace your switch case logic for id R.id.nav_home like below in ProfileActivity class在 ProfileActivity 类中替换 id R.id.nav_home 的 switch case 逻辑,如下所示

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.或者,如果您想保留同一活动的多个实例(ProjectActivity 和 ProfileActivity),那么您可以在 ProfileActivity 的 bottomNavView 的 itemSelectedListener 中为 Intent 实例添加参数。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM