如何修复 getActionBar 方法可能会产生 java.lang.NullPointerException
How to fix getActionBar method may produce java.lang.NullPointerException
我在 activity 中使用工具栏作为我的操作栏。我正在尝试将方法 getActionBar().setDisplayHomeAsUpEnabled(true);
添加到 Activity.java 文件以用于旧设备的向上导航。
该方法在 Android Studio 中产生以下错误消息:
Method invocation may produce 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();
}
});
}
}
首先,您需要将工具栏设置为支持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()
}
谢谢安德鲁的回答。
如果您有导航抽屉或其他使用 getSupportActionBar() 的东西,您需要添加 assert getSupportActionBar() != null;
和平,
示例:
@Override
public void setTitle(CharSequence title) {
mTitle = title;
assert getSupportActionBar() != null;
getSupportActionBar().setTitle(mTitle);
}
试试这个:
private ActionBar getActionBar() {
return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
在getSupportActionBar().setDisplayHomeAsUpEnabled(true);
之前添加assert getSupportActionBar() != null;
实际上 Android Studio 没有向您显示 "error message",它只是一个警告。
一些答案建议使用断言,Dalvik 运行时默认关闭 assertion,因此您必须实际打开它才能真正执行某些操作。在这种情况下(断言已关闭),您实际上所做的只是欺骗 Android Studio 不向您显示警告。另外,我不想在生产代码中使用 "assert"。
在我看来,你应该做的很简单。
if(getActionBar() != null){
getActionBar().setDisplayHomeAsUpEnabled(true);
}
更新:
如果您使用的是 Action Bar 的支持库版本,则应将 getActionBar() 替换为 getSupportActionBar()。
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
我所做的是重写我的基础 Activity 中的 getSupportActionBar()
方法并添加一个 @NonNull
注释。这样,我只在基础 activity 中收到一个关于我如何对具有 @Nullable
注释的东西使用 @NonNull
注释的 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();
}
我创建了一个通用的 class 例如:
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);
P.S。不要忘记将 "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);
或者,您可以断言 actionbar 不 null.Add 在调用您的 actionbar 之前断言
assert getSupportActionBar() != null;
因此,最终片段将如下所示:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
试试这个:
setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}
注意 setSupportActionBar(toolbar) 应该在 getSupportActionBar() 之前。
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
OR
将MainActivity extends AppCompatActivity
替换为public class MainActivity extends AppCompatActivity
只需检查 getSupportActionBar 不等于 null
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Daily Shopping List");
}
如果您要导入
android.app.ActionBar
你必须使用 getActionBar()
如果您要导入
android.support.v7.app.ActionBar
使用 getSupportActionBar()
我在 activity 中使用工具栏作为我的操作栏。我正在尝试将方法 getActionBar().setDisplayHomeAsUpEnabled(true);
添加到 Activity.java 文件以用于旧设备的向上导航。
该方法在 Android Studio 中产生以下错误消息:
Method invocation may produce 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();
}
});
}
}
首先,您需要将工具栏设置为支持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()
}
谢谢安德鲁的回答。 如果您有导航抽屉或其他使用 getSupportActionBar() 的东西,您需要添加 assert getSupportActionBar() != null;
和平,
示例:
@Override
public void setTitle(CharSequence title) {
mTitle = title;
assert getSupportActionBar() != null;
getSupportActionBar().setTitle(mTitle);
}
试试这个:
private ActionBar getActionBar() {
return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
在getSupportActionBar().setDisplayHomeAsUpEnabled(true);
assert getSupportActionBar() != null;
实际上 Android Studio 没有向您显示 "error message",它只是一个警告。
一些答案建议使用断言,Dalvik 运行时默认关闭 assertion,因此您必须实际打开它才能真正执行某些操作。在这种情况下(断言已关闭),您实际上所做的只是欺骗 Android Studio 不向您显示警告。另外,我不想在生产代码中使用 "assert"。
在我看来,你应该做的很简单。
if(getActionBar() != null){
getActionBar().setDisplayHomeAsUpEnabled(true);
}
更新: 如果您使用的是 Action Bar 的支持库版本,则应将 getActionBar() 替换为 getSupportActionBar()。
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
我所做的是重写我的基础 Activity 中的 getSupportActionBar()
方法并添加一个 @NonNull
注释。这样,我只在基础 activity 中收到一个关于我如何对具有 @Nullable
注释的东西使用 @NonNull
注释的 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();
}
我创建了一个通用的 class 例如:
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);
P.S。不要忘记将 "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);
或者,您可以断言 actionbar 不 null.Add 在调用您的 actionbar 之前断言
assert getSupportActionBar() != null;
因此,最终片段将如下所示:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
试试这个:
setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}
注意 setSupportActionBar(toolbar) 应该在 getSupportActionBar() 之前。
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
OR
将MainActivity extends AppCompatActivity
替换为public class MainActivity extends AppCompatActivity
只需检查 getSupportActionBar 不等于 null
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Daily Shopping List");
}
如果您要导入
android.app.ActionBar
你必须使用 getActionBar()
如果您要导入
android.support.v7.app.ActionBar
使用 getSupportActionBar()