首页 > 解决方案 > 如何在片段内的 Spinner 的 onItemSelected() 中使用 getApplication()?

问题描述

我正在尝试使用getApplication()inside aSpinneronItemSelected()方法来尝试获取ViewModelusing ViewModelProviders。在这一点上,我就像 4 个内部类一样,并且java.lang.NullPointerException在启动此活动后几秒钟内我遇到了崩溃。

问题标题非常准确地总结了我的问题。

这是Fragment's 的onCreateView()方法:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.fragment_menu, container, false);
        final MenuActivity menuAct = (MenuActivity) getActivity();
        final MenuViewModel viewModel = ViewModelProviders.of(this, new MenuViewModelFactory(menuAct.getApplication(), MenuActivity.ResID)).get(MenuViewModel.class);
        viewModel.getAllMenuTitles().observe(this, new Observer<String[]>() {
            @Override
            public void onChanged(String[] strings) {
                final Spinner spinner = rootView.findViewById(R.id.spinner);
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), R.layout.support_simple_spinner_dropdown_item, strings);
                adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
                spinner.setAdapter(adapter);

                spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                        menuAct.removeAllTabs();
                        SubMenuViewModel vm = ViewModelProviders.of(getParentFragment(), new SubMenuViewModelFactory(menuAct.getApplication(), i)).get(SubMenuViewModel.class); //← This is the problematic getApplication() 
                        vm.getSubMenus().observe(getActivity(), new Observer<String[]>() {
                            @Override
                            public void onChanged(@Nullable String[] strings) {
                                menuAct.populateTabs(strings);
                            }
                        });
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> adapterView) {

                    }
                });
            }
        });

        return rootView;
    }

这是我的堆栈跟踪:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentActivity android.support.v4.app.Fragment.getActivity()' on a null object reference
    at android.arch.lifecycle.ViewModelProviders.checkActivity(ViewModelProviders.java:50)
    at android.arch.lifecycle.ViewModelProviders.of(ViewModelProviders.java:100)
    at com.whatamidoingwithmylife.splitbill.MenuActivity$PlaceholderFragment$1$1.onItemSelected(MenuActivity.java:198)
    at android.widget.AdapterView.fireOnSelected(AdapterView.java:944)
    at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:933)
    at android.widget.AdapterView.-wrap1(Unknown Source:0)
    at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:898)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

标签: javaandroidnullpointerexceptionfragment

解决方案


覆盖onAttach()以获取活动,如下所示,

private Activity mActivity;

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if (context instanceof Activity){
        mActivity=(Activity) context;
    }

}

然后使用mActivity.getApplication()访问应用程序对象。

如果想要应用上下文,可以从adapterView中获取应用上下文,

adapterView.getContext().getApplicationContext()

如果您的片段附加到 MenuActivity 那么您可以获得应用程序对象,如下所示,

((MenuActivity)adapterView.getContext()).getApplication()


推荐阅读