Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在setContentView()之前调用findViewById()会导致NullPointerException,但并不总是这样?_Android_Nullpointerexception_Findviewbyid_Setcontentview - Fatal编程技术网

Android 在setContentView()之前调用findViewById()会导致NullPointerException,但并不总是这样?

Android 在setContentView()之前调用findViewById()会导致NullPointerException,但并不总是这样?,android,nullpointerexception,findviewbyid,setcontentview,Android,Nullpointerexception,Findviewbyid,Setcontentview,当我调用findViewById()访问按钮时,我会得到一个NullPointerException。我想我明白为什么我会犯这个错误,但我脑子里有些问题还没有解决。 我想我得到这个错误是因为我将findViewById()调用从onCreate()方法内部移到了类范围之外,移到了所有方法之外 因此,现在我正在初始化按钮和编辑文本方法之外的onCreate()方法。 如果我理解正确,这会发生(Null错误),因为setContentView()方法在findViewById()方法之后调用,所以它

当我调用
findViewById()
访问按钮时,我会得到一个
NullPointerException
。我想我明白为什么我会犯这个错误,但我脑子里有些问题还没有解决。 我想我得到这个错误是因为我将
findViewById()
调用从
onCreate()
方法内部移到了类范围之外,移到了所有方法之外

因此,现在我正在初始化
按钮和
编辑文本
方法之外的
onCreate()
方法。 如果我理解正确,这会发生(Null错误),因为
setContentView()
方法在
findViewById()
方法之后调用,所以它会引发异常

但是我不明白的是,我在第二次活动中做了同样的事情,并且工作得很好,没有任何异常。我正在初始化
onCreate()方法之外的按钮等

这确实让我有点困惑。如果能帮我解决这个问题,我将不胜感激

第一项活动

public class FirstActivity extends AppCompatActivity {
 
    private Button signUpButton= findViewById(R.id.lo_signUpButton);
    private Button loginButton = findViewById(R.id.lo_loginButton);
    private EditText username= findViewById(R.id.lo_usernameText);
    private EditText password= findViewById(R.id.lo_passwordText);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set view
        setContentView(R.layout.activity_login);
        Log.i(TAG,"Create "+formatter.format(new Date()));

        //listeners
        signUpButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(LoginActivity.this, SignUpActivity.class));
                finish();
                }
        });

}
public class SecondActivity extends AppCompatActivity {

    private EditText username = findViewById(R.id.su_username);
    private EditText password = findViewById(R.id.su_password);
    private TextView errorText= findViewById(R.id.su_error_msg);
    private Button signUpButton=findViewById(R.id.su_signupButton);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set view
        setContentView(R.layout.activity_signup);
        Log.i(TAG,"Create");

        //listeners
        Button backButton = findViewById(R.id.su_backButton);
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
                Log.i(TAG,"Going Back ");
                finish();
            }
        }); 
第二项活动

public class FirstActivity extends AppCompatActivity {
 
    private Button signUpButton= findViewById(R.id.lo_signUpButton);
    private Button loginButton = findViewById(R.id.lo_loginButton);
    private EditText username= findViewById(R.id.lo_usernameText);
    private EditText password= findViewById(R.id.lo_passwordText);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set view
        setContentView(R.layout.activity_login);
        Log.i(TAG,"Create "+formatter.format(new Date()));

        //listeners
        signUpButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(LoginActivity.this, SignUpActivity.class));
                finish();
                }
        });

}
public class SecondActivity extends AppCompatActivity {

    private EditText username = findViewById(R.id.su_username);
    private EditText password = findViewById(R.id.su_password);
    private TextView errorText= findViewById(R.id.su_error_msg);
    private Button signUpButton=findViewById(R.id.su_signupButton);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set view
        setContentView(R.layout.activity_signup);
        Log.i(TAG,"Create");

        //listeners
        Button backButton = findViewById(R.id.su_backButton);
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
                Log.i(TAG,"Going Back ");
                finish();
            }
        }); 

不能使用此初始化:

public class SecondActivity extends AppCompatActivity {

    private Button signUpButton= findViewById(R.id.lo_signUpButton);
    //....
}
使用:

在第二个活动中,您正在做一些不同的事情:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_signup);
    Button backButton = findViewById(R.id.su_backButton);
    //...
}
这是正确的,因为在调用
setContentView
之后,您在
onCreate
中使用
findViewById
方法声明和初始化
backButton

在第一个活动中,您使用
signUpButton.setOnClickListener
设置侦听器,但是
signUpButton
未初始化(因为它在
onCreate
方法之外)


另外,在第二个活动中,
OnCreate
方法中没有使用初始化错误的其他按钮。

在第二个活动中,您没有使用初始化错误的按钮,一旦使用它们,也会导致异常


您使用了正确初始化的backButton。

答案非常简单。全局变量在调用setContentView()之前初始化,这意味着findViewById()将返回null。findViewById()在找到或为null时返回视图。由于您尚未调用setContentView,因此它无法找到所需的视图

FirstActivity和SecondActivity中的全局变量均为null。 FirstActivity和SecondActivity的区别在于,您不访问SecondActivity中的任何全局变量

在SecondActivity中使用的唯一视图是backButton,它是在调用setContentView后检索到的,因此当然不会引发NullPointerException


始终将变量声明为全局变量,并在onCreate()中初始化它。更好的是,尽量避免使用全局变量,并通过方法参数传递它们。

好的,我也是这么认为的。但是为什么我的第二个活动没有引起任何异常?两者都进行相同的初始化…@Panagiss,因为在第二个活动中您使用的是不同的东西:
Button backButton=findViewById(R.id.su_backButton)而不是
signUpButton.setOnClickListener(新视图.OnClickListener()
@Panagiss我已经更新了答案。在第一个活动中,您正在使用
signUpButton设置侦听器。setOnClickListener
但是
signUpButton
未初始化。在第二个活动中,您在设置侦听器之前正确使用
findViewById
。在
OnCreate
方法。非常感谢!!调用
findViewById()
字段初始值设定项中的字段总是会崩溃。您可能查看了错误的代码,或者运行了过时的生成,或者其他原因。所有给出的答案都是错误的。这与您稍后设置侦听器或以其他方式访问这些字段无关。第一个
findViewById()
调用将立即抛出,远远早于
onCreate()
运行。