调用setSupportActionBar后,在setBackgroundDrawable上发生NullPointerException

时间:2018-01-04 23:35:54

标签: java android

我使用app抽屉布局活动创建了一个应用作为我的主要活动。该应用程序一直很好,但我一直看到用户的崩溃报告: 这是堆栈跟踪:

java.lang.RuntimeException: 
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2984)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14 (ActivityThread.java)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1642)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6776)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1410)
Caused by: java.lang.NullPointerException: 
at android.support.v7.widget.au.setBackgroundDrawable (SourceFile:123)
at android.view.View.setBackground (View.java:19498)
at android.view.View.<init> (View.java:4932)
at android.widget.ImageView.<init> (ImageView.java:150)
at android.widget.ImageButton.<init> (ImageButton.java:85)
at android.widget.ImageButton.<init> (ImageButton.java:81)
at android.support.v7.widget.au.<init> (SourceFile:72)
at android.support.v7.widget.Toolbar.y (SourceFile:1361)
at android.support.v7.widget.Toolbar.a (SourceFile:993)
at android.support.v7.widget.gp.<init> (SourceFile:181)
at android.support.v7.widget.gp.<init> (SourceFile:95)
at android.support.v7.app.be.<init> (SourceFile:68)
at android.support.v7.app.an.a (SourceFile:217)
at android.support.v7.app.x.a (SourceFile:129)
at com.turndapage.navexplorer.activity.MainActivity.onCreate (SourceFile:65)
at android.app.Activity.performCreate (Activity.java:6955)
at android.app.Instrumentation.callActivityOnCreate 
(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2927)

自我的应用发布以来,我遇到了这个问题。我不明白为什么会这样,为什么它永远不会发生在我身上。导致崩溃的行是 setSupportActionBar(工具栏); 这是MainActivity脚本:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

static final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
private SelectedFiles selectedFiles;
public ExplorerFragment explorerFragment = new ExplorerFragment();
private FrameLayout content;

static final int ID_COPY = 5747621;
static final int ID_CUT = 89872154;
static final int ID_ADD = 49878321;
static final int ID_DELETE = 8789451;
static final int ID_RENAME = 72354458;
static final int ID_CLEAR_CLIPBOARD = 77852213;
static final int ID_SELECT_ALL = 89634453;
static final int ID_SELECT_INVERSE = 72156321;
static final int ID_DESELECT_ALL = 75315497;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    selectedFiles = new SelectedFiles(this);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    content = findViewById(R.id.content);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        checkPermissions();
    else
        onPermissionGranted();

    Intent listenerService = new Intent(this, HostNameListenerService.class);
    startService(listenerService);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    //setToExplorer();
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

public SelectedFiles getSelectedFiles() {
    return this.selectedFiles;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    if(selectedFiles != null) {
        if (selectedFiles.getDisplayCopyAction())
            menu.add(0, ID_COPY, 0, getResources().getString(R.string.action_copy)).setIcon(R.drawable.ic_content_copy_white_24dp)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        if (selectedFiles.getDisplayCutAction())
            menu.add(0, ID_CUT, 0, getResources().getString(R.string.action_cut)).setIcon(R.drawable.ic_content_cut_white_24dp)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        if (selectedFiles.getDisplayAddAction())
            menu.add(0, ID_ADD, 0, getResources().getString(R.string.action_add)).setIcon(R.drawable.ic_add_white_24dp)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        if (selectedFiles.getDisplayDeleteAction())
            menu.add(0, ID_DELETE, 0, getResources().getString(R.string.action_delete)).setIcon(R.drawable.ic_delete_white_24dp)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        if (selectedFiles.getDisplayClearClipboardAction())
            menu.add(0, ID_CLEAR_CLIPBOARD, 0, getResources().getString(R.string.action_clear_clipboard)).setIcon(R.drawable.ic_clear_white_24dp);
        if (selectedFiles.getDisplayDeselectAllAction())
            menu.add(0, ID_DESELECT_ALL, 0, getResources().getString(R.string.action_deselect_all)).setIcon(R.drawable.ic_clear_white_24dp)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        if (selectedFiles.getDisplayRenameAction())
            menu.add(0, ID_RENAME, 0, getResources().getString(R.string.action_rename)).setIcon(R.drawable.ic_edit_white_24dp);
    }
    menu.add(0, ID_SELECT_ALL, 0, getResources().getString(R.string.action_select_all)).setIcon(R.drawable.ic_select_all_white_24dp)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    menu.add(0, ID_SELECT_INVERSE, 0, getResources().getString(R.string.action_select_inverse)).setIcon(R.drawable.ic_flip_to_back_white_24dp)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();


    switch (id) {
        case ID_COPY:
            selectedFiles.copy();
            return true;
        case ID_CUT:
            selectedFiles.cut();
            return true;
        case ID_ADD:
            selectedFiles.addFolder();
            return true;
        case ID_DELETE:
            selectedFiles.delete();
            return true;
        case ID_CLEAR_CLIPBOARD:
            selectedFiles.clearClipboard();
            return true;
        case ID_SELECT_ALL:
            selectedFiles.selectAll();
            return true;
        case ID_SELECT_INVERSE:
            selectedFiles.selectInverse();
            return true;
        case ID_DESELECT_ALL:
            selectedFiles.deselectAll();
            return true;
        case ID_RENAME:
            selectedFiles.renameFile();
            return true;
    }

    return super.onOptionsItemSelected(item);
}

似乎崩溃是因为它试图将一个drawable设置为一个不存在的按钮。

编辑: 以下是布局资源:

主要活动

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

app_bar_main

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.turndapage.navexplorer.activity.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<FrameLayout
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?attr/actionBarSize">

</FrameLayout>

</android.support.design.widget.CoordinatorLayout>

我在Android版本5-8上看到了崩溃,这是我的所有应用支持。我自己从未见过它。

1 个答案:

答案 0 :(得分:2)

好。我最终借用了一个Galaxy S7来测试它,因为我看到所有Galaxys都在崩溃。我在调试模式下运行应用程序,一切都很好。在预感中我从Play商店安装它并在启动时崩溃。这让我觉得它与发布版本的变化有关。

默认情况下,gradle构建是:

implementation "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
implementation "com.android.support:support-v4:$rootProject.ext.supportLibraryVersion"
implementation "com.android.support:design:$rootProject.ext.supportLibraryVersion"
implementation 'com.android.support.constraint:constraint-layout:1.0.2'

我将所有实现更改为编译,并修复了崩溃。

我很好奇。这是解决这个问题的最佳方法吗?在发布应用程序之前,我应该知道这件事吗?为什么它对一些用户有用,但不是全部用户?

谢谢!

[编辑]似乎主要问题是我的Wear模块还有一个MainActivity布局,干扰某些设备但不是全部。我想在实现和编译方面的差异解决了这个问题,但最好重新命名wear模块中的类,以便不匹配。