首页 > 解决方案 > 获取 NPE 无法启动活动:即使使用 setContentView 也尝试在空对象引用上调用虚拟方法

问题描述

我正在按照本教程探索 Firebase 并使用三个 java 类使用电子邮件身份验证

  1. 主要活动
  2. 注册活动
  3. 个人资料活动

和三个布局视图。

  1. activity_main.xml
  2. 活动注册.xml
  3. profilepage.xml

[ Youtube 教程] 1 我得到

java.lang.RuntimeException:无法启动活动 ComponentInfo{com.example.firebaselearning/com.example.firebaselearning.RegisterActivity}:java.lang.NullPointerException:尝试调用虚拟方法 'void android.widget.Button.setOnClickListener(android. view.View$OnClickListener)' 在空对象引用上

完全错误

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.firebaselearning, PID: 8008
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.firebaselearning/com.example.firebaselearning.RegisterActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
    at com.example.firebaselearning.RegisterActivity.onCreate(RegisterActivity.java:60)
    at android.app.Activity.performCreate(Activity.java:7136)
    at android.app.Activity.performCreate(Activity.java:7127)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:6669) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

以下是代码(不包括gradle,因为我认为这不是错误的来源)

MainActivity.java

public class MainActivity extends AppCompatActivity {

//views
Button mRegisterBtn, mLogInBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //initialise view
    mRegisterBtn = findViewById(R.id.registerbutton);
    mLogInBtn = findViewById(R.id.login);

    //handle register button click
    mRegisterBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //start register activity
            startActivity(new Intent(MainActivity.this, RegisterActivity.class));
        }
    });
  }
}

注册活动.java

public class RegisterActivity extends AppCompatActivity {

//views
EditText mEmailET, mPassword;
Button mRegistrationBTN;

//progressbar to display progress which registering
ProgressDialog progressDialog;
//declare instance of fireAuth
private FirebaseAuth mAuth;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);

    //actionbar and its title
    ActionBar actionBar = getSupportActionBar();
    actionBar.setTitle("Create Account");

    //enable back button
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setDisplayShowHomeEnabled(true);

    //init
    mEmailET = findViewById(R.id.editTextTextEmailAddress);
    mPassword = findViewById(R.id.editTextTextPassword);
    mRegistrationBTN = findViewById(R.id.registerbutton);

    //initialising firebaseAuth instance
    mAuth = FirebaseAuth.getInstance();

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Registering user ...");


    //handle register btn click
    mRegistrationBTN.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //input email, password
            String email = mEmailET.getText().toString().trim();
            String password = mPassword.getText().toString().trim();
            //validate
            if(Patterns.EMAIL_ADDRESS.matcher(email).matches()){
                //show error and focus to edittext
                mEmailET.setError("Invalid Email");
                mEmailET.setFocusable(true);
            }else if (password.length()<6){
                //set error and focus to password
                mPassword.setError("Password length must be at least 6 characters");
                mPassword.setFocusable(true);
            }else{
                //register the user
                registerUser(email,password);
            }

        }
    });

}

private void registerUser(String email, String password){
    //email and password is valid ,shows progress dialog and start registering user
    progressDialog.show();

    mAuth.createUserWithEmailAndPassword(email,password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, dismiss dialog and start register activity
                        progressDialog.dismiss();
                        FirebaseUser user = mAuth.getCurrentUser();
                        assert user != null;
                        Toast.makeText(RegisterActivity.this,"Registered..."+user.getEmail(), Toast.LENGTH_SHORT).show();
                        startActivity(new Intent(RegisterActivity.this, ProfileActivity.class));
                        finish();
                    } else {
                        // If sign in fails, display a message to the user.
                        progressDialog.dismiss();
                        Toast.makeText(RegisterActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
                    }
                }
            }) .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            //error, dismiss progrss dialog and get and show error message
            progressDialog.dismiss();
            Toast.makeText(RegisterActivity.this,""+e.getMessage(),Toast.LENGTH_SHORT).show();
        }
    });
}
@Override
public boolean onSupportNavigateUp() {
    onBackPressed(); //go previous activity on clicking back
    return super.onSupportNavigateUp();
  }
}

我已经重新验证了我的 xml 文件的名称是否相同。

标签: javaandroidxmlfirebaseandroid-studio

解决方案


由于从作为 MainActivity 视图的 activity_main.xml 布局引用注册按钮,从 RegisterActivity 引用注册按钮而出现错误,该注册按钮在 activity_register.xml 的视图中有另一个注册按钮

很抱歉浪费你的时间。因此,activity_main 中的注册按钮未在 Register.java 中初始化


推荐阅读