Неожиданный жизненный цикл, вызывающий фатальное исключение?

Я разработчик iOS, у меня совершенно нет опыта работы с android, так что простите, если у меня возникли затруднения с выражением моего вопроса:

Я получаю Fatal Exception в приложении для Android, которое мне поручено поддерживать.

Fatal Exception: java.lang.RuntimeException Unable to start activity ComponentInfo{…}: java.lang.NullPointerException

Я вижу из отчета о сбое (прилагается ниже), что сбой происходит в одном из моих фрагментов в методе с именем "bindLocation"

Вот строка, на которой он падает:

            mLocationHeaderTextView.setVisibility(View.VISIBLE);

Очевидно, проблема в том, что mLocationHeaderTextview имеет значение null. mLocationHeaderTextView вводится с помощью roboguice следующим образом:

 @InjectView(R.id.filter_location_header)
TextView mLocationHeaderTextView;

Теперь я думаю, что ошибка вызвана тем, что мой textView не был "введен". Посмотрев трассировку стека, я определил, что это, скорее всего, результат того, что onViewCreated () не был вызван до вызова bindLocation ().

Это где я заблудился, однако. Я очень незнаком с Android, поэтому я не уверен, как это возможно, что мой метод onViewCreated пропускается. Я попробовал миллион вещей на устройстве, чтобы попытаться воспроизвести эту ситуацию, но я не могу. Независимо от того, какие пользовательские действия я могу попробовать, мой метод onViewCreated вызывается, а моя переменная не равна нулю. Возможно, я неправильно читаю трассировку стека. Я надеюсь, что моя трассировка стека ниже предоставит вам достаточно информации, чтобы помочь мне, но если нет, дайте мне знать, что еще я могу рассказать вам о приложении. Я не могу опубликовать свой полный исходный код (так как он не принадлежит мне), но я предоставлю любую информацию, которую смогу.

Большое спасибо за Вашу помощь!

Из моего FilterDrawerFragment:

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_filter_drawer, container, false);

    ButterKnife.inject(this, view);

    return view;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mRulesHeaderReset.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            resetRules();
        }
    });

    if (getActivity() != null && mDrawerLayout == null) {
        mDrawerLayout = (DrawerLayout) getActivity().findViewById(R.id.filter_drawer_layout);

        if (mDrawerLayout != null) {
            mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
                @Override
                public void onDrawerSlide(View view, float v) {

                }

                @Override
                public void onDrawerOpened(View view) {
                    NavigationUtils.invalidateOptionsMenu(getActivity());
                }

                @Override
                public void onDrawerClosed(View view) {
                    notifyFiltersChanged();

                    NavigationUtils.invalidateOptionsMenu(getActivity());
                }

                @Override
                public void onDrawerStateChanged(int i) {

                }
            });

            // set a custom shadow that overlays the main content when the drawer opens
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.END);
        }
    }

    mlocationChangeButton.setOnClickListener(this);

    bindUI();
}

 private void bindUI() {
    if (isAdded() && mConfiguration != null) {

        // bind the location
        bindLocation();
        …
    }
}

private void bindLocation() {
    if (isAdded() && mConfiguration != null && mConfiguration.isLocationEnabled()) {

        // show the location related items
        mLocationHeaderTextView.setVisibility(View.VISIBLE);//Crash reported here.
        …
            }
        });

    }
}


/**
 * Users of this fragment must call this to update the filter configuration
 */
public void updateConfiguration(FilterConfiguration configuration) {
    if (configuration != null && !configuration.equals(mConfiguration)) {
        mConfiguration = configuration;

        bindUI();
    }
}

И updateConfiguration () вызывается из LocationFinderFragment:

 @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if (getArguments() != null) {
          ………
    if (savedInstanceState == null) {
        mFilterDrawerFragment = FilterDrawerFragment.newInstance();
        getChildFragmentManager()
                .beginTransaction()
                .replace(R.id.filter_drawer, mFilterDrawerFragment)
                .commit();

    } else {
        mFilterDrawerFragment = (FilterDrawerFragment) getChildFragmentManager().findFragmentById(R.id.filter_drawer);
    }

    ………         
);
    …………………
    populateFilters();
}


private void populateFilters() {
    // these might be passed into the fragment
    if (mFacets != null) {
        FilterConfiguration config = new FilterConfiguration() {{
        ……………………
        }};

        mFilterDrawerFragment.updateConfiguration(config);

2 ответа

Решение

Теперь я думаю, что вижу проблему.

  1. В roboguice представления внедряются в onViewCreated ().
  2. onViewCreated() называется после onCreateView(),
  3. bindLocation() называется в onCreateView(),

Следовательно, к этому времени представления еще не введены робогисом.

Пожалуйста, попробуйте позвонить bindLocation() в onViewCreated() после звонка super,

Вот как я это исправил. Как вы используете ButterKnife. Без этих настроек ButterKnife бросает NPE.

Перед использованием этой библиотеки вы должны выполнить некоторые настройки в конфигурации ButterKnife Eclipse или ButterKnife Android Studio.

Если вы используете ADT и не обрабатываете аннотации, проверьте это, чтобы установить Android Eclipse - не отображается опция обработки аннотаций

Другие вопросы по тегам