onCreateMenuのgetActionBarでNullPointerExceptionが発生する
対象
- API version を 19→21へ更新した
- SearchViewを使っている
- ActionBarに虫眼鏡マークを出すアレ
- SearchViewに渡す引数としてgetActivity().getActionBar().getThemedContext()とかしてる
- getActivity().getActionBar()でnullになる
原因
なぜAPI19以前は正常に行っていたのか分けがわからないが、以下の理由によりNullPointerExceptionが発生していた。
- onCreateOptionsMenu() は onCreate() の終盤で呼ばれる
- setContentView() 以前に getActivity().getActionBar()を実行するとnullが返却される
問題のコード
public class IssueList extends ListFragment { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { FilterArgument intent = new FilterArgument(); intent.setArgument( getArguments() ); inflater.inflate( R.menu.refresh, menu ); menu_refresh = menu.findItem(R.id.menu_refresh); setupSearchBar(menu); super.onCreateOptionsMenu(menu, inflater); } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) protected void setupSearchBar(Menu menu){ if(! (getActivity() instanceof FragmentActivity)) { return; } ActionBar bar = ((FragmentActivity)getActivity()).getActionBar(); //^^^^^^^^^^^^^^ NullPointerException SearchView search = new SearchView(bar.getThemedContext()); search.setIconifiedByDefault(false); search.setSubmitButtonEnabled(true); search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { //...snip... }); menu.add(android.R.string.search_go) .setIcon(android.R.drawable.ic_menu_search) .setActionView(search) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) ; } }
修正
Activityのコンテキストでもテーマは適用されているので、そのまま使用することにする。
本来はonActivityCreated以降が望ましいが、なぜか正常に処理されるため、タイミングの修正は行わないこととする。
//if(! (getActivity() instanceof FragmentActivity)) { // return; //} //ActionBar bar = ((FragmentActivity)getActivity()).getActionBar(); //^^^^^^^^^^^^^^ NullPointerException //SearchView search = new SearchView(bar.getThemedContext()); SearchView search = new SearchView(getActivity());
参考文献
- 【Android】getActionBar()がNullを返す【3.x】 | 一人男子会
- getActionBar()がnullになるケースの説明あり
- 【翻訳】Android Fragmentへの反対声明 - ninjinkun's diary
- fragmentの状態遷移図(詳細版)がある
- SupportAPIを使用している場合で、21になったときにライフサイクルが変わったのだろうと予測
- Android: When is onCreateOptionsMenu called during Activity lifecycle? - Stack Overflow
- " In case of ICS and Honeycomb onCreateOptionsMenu is called after onCreate and onPostCreate while in Gingerbread and earlier versions it is called after onCreate but before onPostCreate"
- ""