为什么在 class 开头使用 findViewById(R.id.******) 初始化变量时,我的 Android 应用程序崩溃并出现 NullPointerException?
Why does my Android app crash with a NullPointerException when initializing a variable with findViewById(R.id.******) at the beginning of the class?
此代码,顶部的块已注释,运行s 成功:
public class MainActivity extends AppCompatActivity {
/*
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
*/
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
我正在尝试使用
捕获组件的 ID
findViewById(R.id.***)
如您所见,我把这段代码放在了代码最开头的注释中。
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
如果我删除上面的注释并 运行 它(在模拟器和真实设备中),程序会立即崩溃,我很惊讶这里出了什么问题?
我什至尝试使用构造函数初始化相同的东西。
但是如果我把它放在里面 onCreate()
就不会崩溃?为什么?
我试图获取用户名和密码的信息并使用
将其显示到textView_Inputdata
中的文本视图
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
inputdata.setText(username.getText.toString()+" "+password.getText.toString());
有更好或更简单的方法吗?
实例成员变量在实例本身初始化时被初始化。 findViewById()
太早了
在 onCreate()
之前,您的 activity 还没有 findViewById()
内部需要的 Window
。在 setContentView()
之前(您应该在 onCreate()
中调用)也找不到视图。
因此在 onCreate()
和 setContentView()
之后初始化您的视图引用。
添加此代码
EditText username = findViewById(R.id.editText_Username);
EditText password = findViewById(R.id.editText_Password);
TextView inputdata = findViewById(R.id.textView_InputData);
TextView welcome = findViewById(R.id.textView_Welcome);
Button login = findViewById(R.id.button_Login);
Button anotherLogin = findViewById(R.id.button_Login_Another);
在
onCreate();
之后的方法
setContentView(R.layout.activity_main);
嘿,我看到您正在定义和初始化实例变量。
我所做的是定义实例变量 - EditText username
然后在 onCreate
方法中初始化它们 - username = (EditText) findViewById(R.id.editText_Username);
你不初始化实例变量的原因是因为元素在 onCreate
方法中的 setContentView
之后才准备好 - 我可能是错的,但我的最佳实践是定义实例变量,然后在onCreate方法中初始化它们
在设置 setContentView() 之前,您无法初始化视图 items.Because 届时 activity 视图将不存在。
将初始化保留在一个单独的方法中,并在将视图设置为 activity 后调用该方法。
您必须在 onCreate()
中的 setContentView()
之后调用 findViewById()
,在此之前没有 UI/Layout 初始化这就是为什么您的 findViewById()
无法找到 ID并抛出 NullPointerException
.
public class MainActivity extends AppCompatActivity {
public void doLoginOnClick(View v){
String s1 = username . getText ().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar =(Toolbar) findViewById (R.id.toolbar);
setSupportActionBar(toolbar);
EditText username =(EditText) findViewById (R.id.editText_Username);
EditText password =(EditText) findViewById (R.id.editText_Password);
TextView inputdata =(TextView) findViewById (R.id.textView_InputData);
TextView welcome =(TextView) findViewById (R.id.textView_Welcome);
Button login =(Button) findViewById (R.id.button_Login);
Button anotherLogin =(Button) findViewById (R.id.button_Login_Another);
FloatingActionButton fab =(FloatingActionButton) findViewById (R.id.fab);
fab.setOnClickListener(new View . OnClickListener ()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
在 onCreate() 方法之后初始化所有视图
详细了解 activity 生命周期 here
这样想 - 在您告诉 activity 使用哪个用户界面布局 (xml) 之前,它不知道从哪里获取这些视图。
您可以执行 setContentView(R.layout.your_xml) 来告诉 activity 使用哪个布局作为 activity 的用户界面。您将在 onCreate 回调中执行此操作,因为这是执行 'one-time activity level set up' 任务的回调。 setContentView() 就是这样一项任务。
执行此操作后,您可以开始访问布局文件中存在的视图 R.layout.your_xml.
onCreate(...)
{
...
setContentView(R.layout.your_xml)
// Ready to use the views from above xml.
findViewById(R.id.your_view)
...
}
setContentView()
负责对activity的布局进行充气。如果在布局的 inflation 之前使用任何组件,它将崩溃并显示 NullPointerException
.
@Override
protected void onCreate(Bundle savedInstanceState)
{
setContentView(R.layout.activity_layout);
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
}
您仍然可以在 class 的开头声明变量,但您必须在 onCreate
中初始化它。
View Binding 将帮助您避免这些问题:
https://developer.android.com/topic/libraries/view-binding
或者在上面声明视图,在onCreate()中setContentView()之后初始化。
public class MainActivity extends AppCompatActivity {
//Declare view on top
EditText username, password;
TextView inputdata,welcome;
Button login,notherLogin;
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set view
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
} }
此代码,顶部的块已注释,运行s 成功:
public class MainActivity extends AppCompatActivity {
/*
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
*/
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
我正在尝试使用
捕获组件的 IDfindViewById(R.id.***)
如您所见,我把这段代码放在了代码最开头的注释中。
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
如果我删除上面的注释并 运行 它(在模拟器和真实设备中),程序会立即崩溃,我很惊讶这里出了什么问题?
我什至尝试使用构造函数初始化相同的东西。
但是如果我把它放在里面 onCreate()
就不会崩溃?为什么?
我试图获取用户名和密码的信息并使用
将其显示到textView_Inputdata
中的文本视图
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
inputdata.setText(username.getText.toString()+" "+password.getText.toString());
有更好或更简单的方法吗?
实例成员变量在实例本身初始化时被初始化。 findViewById()
在 onCreate()
之前,您的 activity 还没有 findViewById()
内部需要的 Window
。在 setContentView()
之前(您应该在 onCreate()
中调用)也找不到视图。
因此在 onCreate()
和 setContentView()
之后初始化您的视图引用。
添加此代码
EditText username = findViewById(R.id.editText_Username);
EditText password = findViewById(R.id.editText_Password);
TextView inputdata = findViewById(R.id.textView_InputData);
TextView welcome = findViewById(R.id.textView_Welcome);
Button login = findViewById(R.id.button_Login);
Button anotherLogin = findViewById(R.id.button_Login_Another);
在
onCreate();
之后的方法
setContentView(R.layout.activity_main);
嘿,我看到您正在定义和初始化实例变量。
我所做的是定义实例变量 - EditText username
然后在 onCreate
方法中初始化它们 - username = (EditText) findViewById(R.id.editText_Username);
你不初始化实例变量的原因是因为元素在 onCreate
方法中的 setContentView
之后才准备好 - 我可能是错的,但我的最佳实践是定义实例变量,然后在onCreate方法中初始化它们
在设置 setContentView() 之前,您无法初始化视图 items.Because 届时 activity 视图将不存在。
将初始化保留在一个单独的方法中,并在将视图设置为 activity 后调用该方法。
您必须在 onCreate()
中的 setContentView()
之后调用 findViewById()
,在此之前没有 UI/Layout 初始化这就是为什么您的 findViewById()
无法找到 ID并抛出 NullPointerException
.
public class MainActivity extends AppCompatActivity {
public void doLoginOnClick(View v){
String s1 = username . getText ().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar =(Toolbar) findViewById (R.id.toolbar);
setSupportActionBar(toolbar);
EditText username =(EditText) findViewById (R.id.editText_Username);
EditText password =(EditText) findViewById (R.id.editText_Password);
TextView inputdata =(TextView) findViewById (R.id.textView_InputData);
TextView welcome =(TextView) findViewById (R.id.textView_Welcome);
Button login =(Button) findViewById (R.id.button_Login);
Button anotherLogin =(Button) findViewById (R.id.button_Login_Another);
FloatingActionButton fab =(FloatingActionButton) findViewById (R.id.fab);
fab.setOnClickListener(new View . OnClickListener ()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
在 onCreate() 方法之后初始化所有视图
详细了解 activity 生命周期 here
这样想 - 在您告诉 activity 使用哪个用户界面布局 (xml) 之前,它不知道从哪里获取这些视图。
您可以执行 setContentView(R.layout.your_xml) 来告诉 activity 使用哪个布局作为 activity 的用户界面。您将在 onCreate 回调中执行此操作,因为这是执行 'one-time activity level set up' 任务的回调。 setContentView() 就是这样一项任务。
执行此操作后,您可以开始访问布局文件中存在的视图 R.layout.your_xml.
onCreate(...)
{
...
setContentView(R.layout.your_xml)
// Ready to use the views from above xml.
findViewById(R.id.your_view)
...
}
setContentView()
负责对activity的布局进行充气。如果在布局的 inflation 之前使用任何组件,它将崩溃并显示 NullPointerException
.
@Override
protected void onCreate(Bundle savedInstanceState)
{
setContentView(R.layout.activity_layout);
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
}
您仍然可以在 class 的开头声明变量,但您必须在 onCreate
中初始化它。
View Binding 将帮助您避免这些问题:
https://developer.android.com/topic/libraries/view-binding
或者在上面声明视图,在onCreate()中setContentView()之后初始化。
public class MainActivity extends AppCompatActivity {
//Declare view on top
EditText username, password;
TextView inputdata,welcome;
Button login,notherLogin;
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set view
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
} }