空对象引用上的 navigationView setText 致命异常
navigationView setText fatal exception on a null object reference
好的,所以我一直在寻找解决这个问题的办法,但我找到的所有解决办法都不起作用。我正在尝试将我的 navigationView 中的登录按钮的文本更改为登录 Out/Sign 取决于他们是否登录,然后在他们按下按钮时发送他们登录或注销。出于某种原因,我的应用程序因空对象引用(下面的一些日志)出现致命异常而崩溃。我做错了什么?
我创建了 "signInOutText();" 所以我可以尝试将它放在不同的位置,它目前在 onResume 中,但我也尝试过在 onCreate 中,并且最初将它全部放在 onResume 中。希望我只是忽略了一些简单的事情。我从下面的 MainActivity.java 中裁剪了一些我的代码,所以它不是很长,但如果您需要查看完整内容,请告诉我。
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
String category;
MenuItem mPreviousMenuItem;
private ProgressDialog mProgressDialog;
String providerId,uid,name,email;
Uri photoUrl;
private static final String TAG = "MainActivity";
// set name of your preferences list
private static String MY_PREFERENCES = "Settings";
String userNameLoad, emailLoad, profileLoad;
TextView usernameTextView, emailTextView, signInTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setCheckable(true);
menuItem.setChecked(true);
if (mPreviousMenuItem != null) {
mPreviousMenuItem.setChecked(false);
}
mPreviousMenuItem = menuItem;
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
//Replacing the main content with fragments
case R.id.home:
//code for button
break;
case R.id.cat1:
//code for button
break;
case R.id.signIn:
signInOut();
break;
default:
break;
}
return true;
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){
@Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
@Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we don't want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
private void signInOutText() {
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Get header xml from navigationView
View header = navigationView.getHeaderView(0);
//Check if user logged in, change sign in sign out button to correct text
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
signInTextView = (TextView) header.findViewById(R.id.signIn);
signInTextView.setText(R.string.sign_out);
} else {
signInTextView = (TextView) header.findViewById(R.id.signIn);
signInTextView.setText(R.string.sign_in);
}
}
private void signInOut(){
//TODO add Code .... if logged in logout
Intent intent = new Intent(MainActivity.this, ChooserActivity.class);
startActivity(intent);
finish();
}
public void setActionBarTitle(String title) {
if(getSupportActionBar() != null){
getSupportActionBar().setTitle(title);
}
}
@Override
public void onResume() {
super.onResume();
// Set title
setActionBarTitle(getString(R.string.app_name));
signInOutText();
}
}
日志
Unable to resume activity {com.test.app/com.test.app.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.TextView.setText(int)' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4156)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access00(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference
at com.test.app.MainActivity.signInOutText(MainActivity.java:203)
at com.test.app.MainActivity.onResume(MainActivity.java:307)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
at android.app.Activity.performResume(Activity.java:6987)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access00(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<include
layout="@layout/toolbar"
/>
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/header"
app:menu="@menu/drawer"
/>
menu/drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/drawer_group"
android:checkable="true">
<item
android:id="@+id/home"
android:checked="false"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/home_string" />
</group>
<group android:id="@+id/group_cat"
android:checkable="true">
<item
android:id="@+id/menuCategories"
android:title="@string/categories_string"
android:layout_gravity="bottom">
<menu>
<item
android:id="@+id/cat1"
android:checked="false"
android:icon="@drawable/ic_inbox_black"
android:title="@string/cat1_string" />
</menu>
</item>
</group>
<group android:id="@+id/group_signInOut"
android:checkable="true">
<item
android:id="@+id/signIn"
android:checked="false"
android:icon="@drawable/ic_power_settings_new_black_24dp"
android:title="@string/sign_in" />
</group>
</menu>
感谢您的帮助!
好的,所以我意识到我正在尝试更新菜单 "item" 而不是 textView,所以这产生了很大的不同。这是我在 signInOutText() 中使用的代码,以使其正常工作:
private void signInOutText() {
// get menu from navigationView
Menu menu = navigationView.getMenu();
// find MenuItem you want to change
MenuItem nav_signIn = menu.findItem(R.id.signIn);
//Check if user logged in, change sign in/out button to correct text
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
nav_signIn.setTitle(R.string.sign_out);
} else {
nav_signIn.setTitle(R.string.sign_in);
}
}
希望对大家有所帮助!感谢您的帮助!
好的,所以我一直在寻找解决这个问题的办法,但我找到的所有解决办法都不起作用。我正在尝试将我的 navigationView 中的登录按钮的文本更改为登录 Out/Sign 取决于他们是否登录,然后在他们按下按钮时发送他们登录或注销。出于某种原因,我的应用程序因空对象引用(下面的一些日志)出现致命异常而崩溃。我做错了什么?
我创建了 "signInOutText();" 所以我可以尝试将它放在不同的位置,它目前在 onResume 中,但我也尝试过在 onCreate 中,并且最初将它全部放在 onResume 中。希望我只是忽略了一些简单的事情。我从下面的 MainActivity.java 中裁剪了一些我的代码,所以它不是很长,但如果您需要查看完整内容,请告诉我。
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
String category;
MenuItem mPreviousMenuItem;
private ProgressDialog mProgressDialog;
String providerId,uid,name,email;
Uri photoUrl;
private static final String TAG = "MainActivity";
// set name of your preferences list
private static String MY_PREFERENCES = "Settings";
String userNameLoad, emailLoad, profileLoad;
TextView usernameTextView, emailTextView, signInTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setCheckable(true);
menuItem.setChecked(true);
if (mPreviousMenuItem != null) {
mPreviousMenuItem.setChecked(false);
}
mPreviousMenuItem = menuItem;
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
//Replacing the main content with fragments
case R.id.home:
//code for button
break;
case R.id.cat1:
//code for button
break;
case R.id.signIn:
signInOut();
break;
default:
break;
}
return true;
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){
@Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
@Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we don't want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
private void signInOutText() {
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Get header xml from navigationView
View header = navigationView.getHeaderView(0);
//Check if user logged in, change sign in sign out button to correct text
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
signInTextView = (TextView) header.findViewById(R.id.signIn);
signInTextView.setText(R.string.sign_out);
} else {
signInTextView = (TextView) header.findViewById(R.id.signIn);
signInTextView.setText(R.string.sign_in);
}
}
private void signInOut(){
//TODO add Code .... if logged in logout
Intent intent = new Intent(MainActivity.this, ChooserActivity.class);
startActivity(intent);
finish();
}
public void setActionBarTitle(String title) {
if(getSupportActionBar() != null){
getSupportActionBar().setTitle(title);
}
}
@Override
public void onResume() {
super.onResume();
// Set title
setActionBarTitle(getString(R.string.app_name));
signInOutText();
}
}
日志
Unable to resume activity {com.test.app/com.test.app.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.TextView.setText(int)' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4156)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access00(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(int)' on a null object reference
at com.test.app.MainActivity.signInOutText(MainActivity.java:203)
at com.test.app.MainActivity.onResume(MainActivity.java:307)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
at android.app.Activity.performResume(Activity.java:6987)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access00(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<include
layout="@layout/toolbar"
/>
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/header"
app:menu="@menu/drawer"
/>
menu/drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/drawer_group"
android:checkable="true">
<item
android:id="@+id/home"
android:checked="false"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/home_string" />
</group>
<group android:id="@+id/group_cat"
android:checkable="true">
<item
android:id="@+id/menuCategories"
android:title="@string/categories_string"
android:layout_gravity="bottom">
<menu>
<item
android:id="@+id/cat1"
android:checked="false"
android:icon="@drawable/ic_inbox_black"
android:title="@string/cat1_string" />
</menu>
</item>
</group>
<group android:id="@+id/group_signInOut"
android:checkable="true">
<item
android:id="@+id/signIn"
android:checked="false"
android:icon="@drawable/ic_power_settings_new_black_24dp"
android:title="@string/sign_in" />
</group>
</menu>
感谢您的帮助!
好的,所以我意识到我正在尝试更新菜单 "item" 而不是 textView,所以这产生了很大的不同。这是我在 signInOutText() 中使用的代码,以使其正常工作:
private void signInOutText() {
// get menu from navigationView
Menu menu = navigationView.getMenu();
// find MenuItem you want to change
MenuItem nav_signIn = menu.findItem(R.id.signIn);
//Check if user logged in, change sign in/out button to correct text
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
nav_signIn.setTitle(R.string.sign_out);
} else {
nav_signIn.setTitle(R.string.sign_in);
}
}
希望对大家有所帮助!感谢您的帮助!