我在我的片段中使用了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>
如果您需要更多信息,请与我们联系。
编辑:为什么这被标记为&#34;如何修复NullPointerException&#34;?这与将其标记为&#34;如何修复错误&#34;的复制一样明智。 :(
编辑2:对不起,伙计们。正如我刚刚意识到我为onCreateOptionsMenu方法发布了错误的代码。我的代码片段来自SignSearchActitivity。唯一真正的区别在于,在调用getSystemService之前调用片段getActivity()。所以getActivty()返回null。为什么 occassionaly 发生在片段的onCreateOptionsMenu()方法中?答案 0 :(得分:0)
问题在于
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
如果对象为null(意味着getSystemService(Context.SEARCH_SERVICE);
返回了一个空对象),该怎么办?它会抛出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.
}
答案 1 :(得分:0)
我认为您正面临此错误,因为您正在从片段调用活动,即使它未创建。您应该在执行onActivityCreated()函数之后或期间调用getActivity(),该函数会通知创建活动。从onCreate()方法调用OnCreateOptionsMenu(),因此可能不会在该时间点创建您的活动。 有关详细信息,请参阅此链接 https://developer.android.com/guide/components/fragments.html
答案 2 :(得分:-1)
你忘了打电话给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()));
}