如何解决getActionBar方法可能会产生java.lang.NullPointerException

我在工作中使用工具栏作为我的操作栏。 我试图添加方法getActionBar().setDisplayHomeAsUpEnabled(true); 到旧版设备的向上导航的Activity.java文件。

该方法在Android Studio中产生以下错误消息:

方法调用可能会产生java.lang.NullPointerException

工具栏上的导航工具在新设备上工作正常…现在我想弄清楚如何确保它适用于较旧的设备。 请指教。

从build.gradle:

 dependencies { compile "com.android.support:appcompat-v7:22.1.0" } 

从AndroidManifest.xml:

 android:theme="@style/Theme.AppCompat.NoActionBar.FullScreen" 

从styles.xml中

 <style name="Theme.AppCompat.NoActionBar.FullScreen" parent="AppTheme"> <item name="android:windowNoTitle">true</item> <item name="windowActionBar">false</item> <item name="android:windowFullscreen">true</item> 

来自Activity.java

 public class CardViewActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cardviewinput); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { // Up navigation to the parent activity for 4.0 and earlier getActionBar().setDisplayHomeAsUpEnabled(true); toolbar.setNavigationIcon(R.drawable.ic_action_previous_item); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); } } 

其实Android Studio不会显示“错误信息”,这只是一个警告。

有些答案提出使用断言,Dalvik运行时默认closures断言 ,所以你必须真正把它打开,实际上做一些事情。 在这种情况下(断言被closures),你实质上只是在欺骗Android Studio而不向你显示警告。 另外,我不想在生产代码中使用“assert”。

在我看来,你应该做的很简单。

 if(getActionBar() != null){ getActionBar().setDisplayHomeAsUpEnabled(true); } 

更新:如果您使用操作栏的支持库版本,则应该将getActionBar()replace为getSupportActionBar()。

 if(getSupportActionBar() != null){ getSupportActionBar().setDisplayHomeAsUpEnabled(true); } 

首先,您需要将工具栏设置为支持的ActionBar。 那么如果你确定它会一直在那里,只要将它断言为!= null。 这将告诉编译器它不会为空,所以空检查通过。

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cardviewinput); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); assert getSupportActionBar() != null; getSupportActionBar().setDisplayHomeAsUpEnabled(true); // it's getSupportActionBar() if you're using AppCompatActivity, not getActionBar() } 

谢谢安德鲁你的回答。 如果你有一个Nav抽屉或其他使用getSupportActionBar()的东西,你需要添加断言getSupportActionBar()!= null;

和平,

例:

 @Override public void setTitle(CharSequence title) { mTitle = title; assert getSupportActionBar() != null; getSupportActionBar().setTitle(mTitle); } 

尝试这个 :

 private ActionBar getActionBar() { return ((AppCompatActivity) getActivity()).getSupportActionBar(); } 

我所做的是重写我的基本活动中的getSupportActionBar()方法,并添加@NonNull注释。 这样,我只在基本活动中得到一个关于如何使用@NonNull注释来注释具有@Nullable注释的lint警告。

  @NonNull @Override public ActionBar getSupportActionBar() { // Small hack here so that Lint does not warn me in every single activity about null // action bar return super.getSupportActionBar(); } 

add assert getSupportActionBar() != null; 之前getSupportActionBar().setDisplayHomeAsUpEnabled(true);

我创build了一个通用的类,如:

 public final class Cast { private Cast() {} /** * Helps to eliminate annoying NullPointerException lint warning. */ @android.support.annotation.NonNull public static <T> T neverNull(T value) { return value; } } 

那么我可以使用它的任何调用NullPointerException警告,我相信它永远不会发生,例如

 final ActionBar actionBar = Cast.neverNull(getSupportActionBar()); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); 

PS不要忘记添加“com.android.support:support- annotations”到您的gradle文件。

  if(actionBar != null) { actionBar.setHomeButtonEnabled(true); actionBar.setBackgroundDrawable(ContextCompat.getDrawable(mContext, R.drawable.action_bar_gradient)); } 

使用这个主题: android:theme="@style/Theme.AppCompat.Light.NoActionBar"

 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle("Title"); setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); actionBar.setHomeButtonEnabled(true); actionBar.setHomeAsUpIndicator(R.drawable.ic_action_previous_item); actionBar.setDisplayHomeAsUpEnabled(true);