如何修复getActionBar方法可能会产生java.lang.NullPointerException


73

我在活动中使用工具栏作为操作栏。我正在尝试将该方法添加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();
            }
        });
    }

}

1
您的主题不是没有ActionBar的主题吗?
juunas 15-4-22

Answers:


127

实际上,Android Studio不会向您显示“错误消息”,而只是警告。

一些答案建议使用断言,Dalvik运行时默认情况下已关闭断言,因此您必须将其打开才能真正执行某项操作。在这种情况下(断言已关闭),您实际上所做的只是在欺骗Android Studio而不向您显示警告。另外,我不希望在生产代码中使用“断言”。

我认为,您应该做的非常简单。

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

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

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

2
虽然我最初使用assert来“解决”警告,但我同意您推荐的代码比assert hack更好。答案已被接受并接受。请注意,我将AppCompatActivity用作类,因此必须在解决方案中使用getSupportActionBar()而不是上面显示的getActionBar()。
AJW

4
为什么android studio对于其他方法(如getSupportActionBar()。setTitle())不给出相同的警告?
Piyush Kukadiya'5

我正在使用getSupportActionBar()!= null,但我的工具栏上仍然抛出空指针。有人知道发生了什么吗?我已经尝试了断言行,它也只抛出一个空指针!到底是怎么回事!??!?!?!
ZooMagic'3

@ZooMagic引发NPE的原因不同。我建议您搜索与您的问题类似的其他问题,或将您的代码发布在新问题上。您需要共享布局文件,清单和活动代码。
亚当·加尼

34

首先,您需要将工具栏设置为支持ActionBar。然后,如果您确定它将一直存在,则将其断言为!= null。这将告诉编译器它不会为null,因此可以通过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()
}

好的,看起来不错,但是断言行在Android Studio中生成“无法解析符号'getSupportActionBar'”错误。应该是“ getSupportActionBar()”吗?请指教。
AJW 2015年

1
您只能在扩展AppCompatActivity或FragmentActivity时访问getSupportActionBar
Sheychan 2015年

8

谢谢安德鲁的回答。如果您有导航抽屉或使用getSupportActionBar()的其他工具,则需要添加assert getSupportActionBar()!= null;

和平,

例:

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

3
这对生产有效还是仅对测试有效?
gian1200

gian1200我不确定。一个好问题。我打算很快发布我的应用程序,因此在发布之前,我将进行研究……谢谢。
斯科特

我的猜测是编译器会将其更改为“如果为null,则抛出assertExeption”;不允许您处理错误。
gian1200

4

尝试这个 :

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

3

我所做的是getSupportActionBar()在我的基本Activity中覆盖该方法并添加了@NonNull注释。这样,我在基本活动中仅收到一个关于我如何@NonNull对具有@Nullable注释的内容使用注释的棉绒警告。

    @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();
    }

感谢您的回答。我不知道使用皮棉。您能否评论您的答案与上方的Adam Ghani答案相比有何优势?
AJW'4

使用亚当的方法,您必须在所有活动中编写if语句。使用我的方法,您只需要在基础活动中覆盖getSupportActionBar,其余代码将像以前一样。
Catalin Morosan '16

3

我创建了一个通用类,例如:

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别忘了在gradle文件中添加“ com.android.support:support-annotations”。


2

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


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

0

使用这个主题: 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);

0

或者您可以断言actionbar不为null。在调用actionbar之前添加断言,如下所示

assert getSupportActionBar() != null;

因此,最终的片段如下所示:

    setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
    assert getSupportActionBar() != null;
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

0

尝试这个 :

setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}

请注意,setSupportActionBar(toolbar)应该在getSupportActionBar()之前。


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

替换MainActivity extends AppCompatActivitypublic class MainActivity extends AppCompatActivity


0

只需检查getSupportActionBar不等于null

    setSupportActionBar(toolbar);

    if(getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Daily Shopping List");
    }

0

如果要导入

android.app.ActionBar 

您必须使用getActionBar()

如果您正在导入

android.support.v7.app.ActionBar

使用getSupportActionBar()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.