构建apk后出现错误

8

在生成已签名的apk后,操作栏视图(共享操作提供程序和搜索视图)崩溃。当我从Android Studio调试应用程序时,它可以工作,但是当我生成已签名的apk并将应用程序安装到设备上时,我会遇到像这样的错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setQueryHint(java.lang.CharSequence)' on a null object reference
            at tm.veriloft.ertir.ui.SearchActivity.onCreateOptionsMenu(Unknown Source)
            at android.app.Activity.onCreatePanelMenu(Activity.java:2820)
            at android.support.v4.app.o.onCreatePanelMenu(Unknown Source)
            at android.support.v7.app.e.a(Unknown Source)
            at android.support.v7.app.g.a(Unknown Source)
            at android.support.v7.widget.as.a(Unknown Source)
            at android.support.v7.internal.a.a.j(Unknown Source)
            at android.support.v7.internal.a.b.run(Unknown Source)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

或者
 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.ah.a(android.content.Intent)' on a null object reference
            at tm.veriloft.ertir.ui.BlogViewActivity.onCreateOptionsMenu(Unknown Source)
            at android.app.Activity.onCreatePanelMenu(Activity.java:2820)
            at android.support.v4.app.o.onCreatePanelMenu(Unknown Source)
            at android.support.v7.app.e.a(Unknown Source)
            at android.support.v7.app.g.a(Unknown Source)
            at android.support.v7.widget.as.a(Unknown Source)
            at android.support.v7.internal.a.a.j(Unknown Source)
            at android.support.v7.internal.a.b.run(Unknown Source)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我正在使用支持库和工具栏的最新版本。(通过设置 setSupportActionBar(mToolbar) )。

SearchView xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ertir="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:title="@string/title_activity_search"
        ertir:showAsAction="always"
        ertir:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

Java

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.search, menu);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        mSearchView = (SearchView) searchItem.getActionView();
        mSearchView.setQueryHint(getString(R.string.search_hint));
        mSearchView.setFocusable(true);
        mSearchView.setIconified(false);
        mSearchView.requestFocusFromTouch();
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                mSearchView.clearFocus(); //Hide keyboard
                search(query, searchTypeArray.get(searchTypeSpinner.getSelectedItemPosition()).getType());
                return false;
            }

            @Override
            public boolean onQueryTextChange(String query) {
                if (searchTypeArray.get(searchTypeSpinner.getSelectedItemPosition()).getType().equals("blogs"))
                    searchAfter(1100, query, searchTypeArray.get(searchTypeSpinner.getSelectedItemPosition()).getType());
                else
                    search(query, searchTypeArray.get(searchTypeSpinner.getSelectedItemPosition()).getType());
                return false;
            }
        });
        return true;
    }

我该如何解决这个问题?就像上面所说的那样,只有在签名apk后才会出现错误。


可能是什么是空指针异常,如何修复它?的重复问题。 - 323go
找出什么是“null”,并确保它不是。 - 323go
@323go 我知道(SearchView) searchItem.getActionView();会返回null。但是我不知道为什么在生成apk后才出现这个错误,而在调试时却没有。 - alashow
而且这不是那个问题的重复。 - alashow
你是否正在导出支持库? - 323go
3个回答

16

在proguard-rules.pro中,添加以下行以排除SearchView类:'-keep class android.support.v7.widget.** { *; }',然后创建build。我是这样解决的。


谢谢你,你救了我的一天,我因为这个错误差点放弃了使用Proguard :) - Ashraf Alshahawy
2
比仅禁用Proguard更好的答案。非常感谢! - Felix Edelmann
1
谢谢,非常有帮助。 - user3910670

4

这是因为您没有正确配置progaurd。在您的build.gradle文件中,在buildTypes和“release”下将runProguard true更改为runProguard false,然后生成签名APK并进行测试。如果一切顺利,请尝试学习如何正确配置progaurd :)


Progaurd可能会删除它认为没有使用的代码,但是您的应用程序实际上可能需要该代码。在这种情况下,您必须识别该类并将其添加到Prograurd配置中,例如-keep public class <MyClass>。有关更多信息,请访问http://developer.android.com/tools/help/proguard.html。 - Panther
最好使用-keep class android.support.v7.widget.SearchView { *; },而不是禁用proguard。 - Prashanth

1

这对我有用,

在位于 app 文件夹内的 proguard-rules.pro 文件中添加以下行:

-keep class android.support.v7.widget.SearchView { *; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接