簡體   English   中英

在片段的onCreateOptionsMenu()中使用getActivity()偶爾會拋出一個NPE

[英]Using getActivity() in onCreateOptionsMenu() of a fragment occasionally throws an NPE

我在我的片段中使用了SearchManager。 不幸的是,使用該方法調用getActivity()。getSystemService(Context.SEARCH_SERVICE) 偶爾拋出一個NullPointerException。 在儀器化的Espresso單元測試和正常使用期間都會發生這種情況。 當我再次運行測試時,一切都很好。 你能告訴我怎么解決這個問題嗎? 謝謝。

堆棧跟蹤:

06-05 16:10:59.162 19183 19183 D AndroidRuntime: Shutting down VM
06-05 16:10:59.188 19183 19183 E AndroidRuntime: FATAL EXCEPTION: main
06-05 16:10:59.188 19183 19183 E AndroidRuntime: Process: foo.bar.baz, PID: 19183
06-05 16:10:59.188 19183 19183 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.app.Activity.getSystemService(java.lang.String)' on a null object reference
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at foo.bar.baz.sign_browser.SignBrowserFragment.onCreateOptionsMenu(SignBrowserFragment.java:139)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.app.Fragment.performCreateOptionsMenu(Fragment.java:2133)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:1945)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.app.Activity.onCreatePanelMenu(Activity.java:2834)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:298)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:241)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v7.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:443)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.support.v7.app.ToolbarActionBar$1.run(ToolbarActionBar.java:60)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5343)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
06-05 16:10:59.188 19183 19183 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
06-05 16:10:59.227 835 1557 I WindowManager: Screen frozen for +393ms due to AppWindowToken{19c5842b token=Token{34cb447a ActivityRecord{10afa8a5 u0 foo.bar.baz/.activities.MainActivity t4133}}}
06-05 16:10:59.233 835 1557 W ActivityManager: Force finishing activity 1 foo.bar.baz/.activities.MainActivity

SignBrowserFragment.onCreateOptionsMenu()

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    Log.d(TAG, "onCreateOptionsMenu " + hashCode());
    inflater.inflate(R.menu.options_sign_browser, menu);
    final MenuItem item = menu.findItem(R.id.action_toggle_starred);
    if (this.showStarredOnly) {
        item.setIcon(R.drawable.ic_sign_browser_grade_checked);
    } else {
        item.setIcon(R.drawable.ic_sign_browser_grade);
    }
    final SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
    final MenuItem searchItem = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
}

我正在使用SignBrowserFragment,它包含在MainActivity中,用於為搜索添加選項菜單項。 實際搜索在單獨的SignSearch活動中執行。

清單文件:

    <activity
        android:name=".activities.MainActivity"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            android:name="android.app.default_searchable"
            android:value=".sign_browser.search.SignSearchActivity" />
    </activity>
    <activity
        android:name=".sign_browser.search.SignSearchActivity"
        android:parentActivityName=".activities.MainActivity"
        tools:ignore="UnusedAttribute">
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MainActivity" />
    </activity>

如果您需要更多信息,請與我們聯系。

編輯:為什么這標記為“如何修復NullPointerException”的副本? 這與將其標記為“如何修復錯誤”的副本一樣明智。 :(

編輯2:對不起,伙計們。 正如我剛剛意識到我為onCreateOptionsMenu方法發布了錯誤的代碼。 我的代碼片段來自SignSearchActitivity。 唯一真正的區別在於,在調用getSystemService之前調用片段getActivity()。 所以getActivty()返回null。 為什么會出現這種occassionaly片段的onCreateOptionsMenu()方法中發生的呢?

問題在於

searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

如果對象為null(表示getSystemService(Context.SEARCH_SERVICE);返回null對象)該怎么辦? 它會拋出NPE,對吧。

將您的代碼更改為:

 if(searchManager != null){
      searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    }
else{
     // Can't perform the search because of null object message to the user (or) log (or) console.
    }

我認為你正面臨這個錯誤,因為你正在從片段調用活動,即使它沒有被創建。 您應該在執行onActivityCreated()函數之后或期間調用getActivity(),該函數會通知創建活動。 從onCreate()方法調用OnCreateOptionsMenu(),因此可能不會在該時間點創建您的活動。 有關詳細信息, 參閱此鏈接https://developer.android.com/guide/components/fragments.html

你忘了打電話給super.onCreateOptionsMenu(..)

@Override public void onCreateOptionsMenu(菜單菜單,MenuInflaterinflater){

 Log.d(TAG, "onCreateOptionsMenu " + hashCode()); super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.options_sign_browser, menu); final MenuItem item = menu.findItem(R.id.action_toggle_starred); if (this.showStarredOnly) { item.setIcon(R.drawable.ic_sign_browser_grade_checked); } else { item.setIcon(R.drawable.ic_sign_browser_grade); } final SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); final MenuItem searchItem = menu.findItem(R.id.action_search); final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); 

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM