Неожиданный жизненный цикл, вызывающий фатальное исключение?
Я разработчик 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 ответа
Теперь я думаю, что вижу проблему.
- В roboguice представления внедряются в onViewCreated ().
onViewCreated()
называется послеonCreateView()
,bindLocation()
называется вonCreateView()
,
Следовательно, к этому времени представления еще не введены робогисом.
Пожалуйста, попробуйте позвонить bindLocation()
в onViewCreated()
после звонка super
,
Вот как я это исправил. Как вы используете ButterKnife. Без этих настроек ButterKnife бросает NPE.
Перед использованием этой библиотеки вы должны выполнить некоторые настройки в конфигурации ButterKnife Eclipse или ButterKnife Android Studio.
Если вы используете ADT и не обрабатываете аннотации, проверьте это, чтобы установить Android Eclipse - не отображается опция обработки аннотаций