导致致命异常的意外生命周期?
Unexpected lifecycle causing Fatal Exception?
我是一名 iOS 开发人员,完全没有使用 android 的经验,所以如果我难以表达我的问题,请原谅我:
我负责维护的 android 应用程序出现致命异常。
Fatal Exception: java.lang.RuntimeException Unable to start activity ComponentInfo{…}: java.lang.NullPointerException
我可以从崩溃报告(附在下面)中看到,崩溃发生在我的一个片段中的一个名为 "bindLocation"
的方法中
这是它崩溃的行:
mLocationHeaderTextView.setVisibility(View.VISIBLE);
很明显问题是 mLocationHeaderTextview 为空。 mLocationHeaderTextView使用roboguice注入如下:
@InjectView(R.id.filter_location_header)
TextView mLocationHeaderTextView;
现在,我认为错误是因为我的 textView 不是 'injected'。查看堆栈跟踪后,我确定这可能是在调用 bindLocation() 之前未调用 onViewCreated() 的结果。
然而,这就是我迷路的地方。我对 android 非常陌生,所以我不确定我的 onViewCreated 方法怎么可能被跳过。我已经在设备上尝试了一百万种方法来尝试重现这种情况,但我做不到。无论我想尝试什么用户操作,都会调用我的 onViewCreated 方法并且我的变量是非 Null 的。也许我误读了堆栈跟踪。我希望下面的堆栈跟踪可以为大家提供足够的信息来帮助我,但如果没有,请告诉我关于该应用程序我还能告诉你什么。我无法 post 我的完整源代码(因为它不属于我),但我会尽我所能提供任何信息。
非常感谢您的帮助!
来自我的 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);
现在我想我明白了问题所在。
- 在 roboguice 中,视图被注入 onViewCreated()。
onViewCreated()
在 onCreateView()
之后调用。
bindLocation()
在 onCreateView()
中调用。
因此,此时 roboguice 尚未注入视图。
请尝试在 onViewCreated()
调用 super
后调用 bindLocation()
。
这就是我解决这个问题的方法。当你使用 ButterKnife 时。 如果没有这些配置,ButterKnife 会抛出 NPE。
在你使用这个库之前你必须做一些配置 ButterKnife Eclipse Configuration 或者
ButterKnife Android Studio Configuration
如果您正在使用 ADT 并且缺少 Annototion Processing 检查此以安装 Android Eclipse - Cannot see annotation processing option
我是一名 iOS 开发人员,完全没有使用 android 的经验,所以如果我难以表达我的问题,请原谅我:
我负责维护的 android 应用程序出现致命异常。
Fatal Exception: java.lang.RuntimeException Unable to start activity ComponentInfo{…}: java.lang.NullPointerException
我可以从崩溃报告(附在下面)中看到,崩溃发生在我的一个片段中的一个名为 "bindLocation"
的方法中这是它崩溃的行:
mLocationHeaderTextView.setVisibility(View.VISIBLE);
很明显问题是 mLocationHeaderTextview 为空。 mLocationHeaderTextView使用roboguice注入如下:
@InjectView(R.id.filter_location_header)
TextView mLocationHeaderTextView;
现在,我认为错误是因为我的 textView 不是 'injected'。查看堆栈跟踪后,我确定这可能是在调用 bindLocation() 之前未调用 onViewCreated() 的结果。
然而,这就是我迷路的地方。我对 android 非常陌生,所以我不确定我的 onViewCreated 方法怎么可能被跳过。我已经在设备上尝试了一百万种方法来尝试重现这种情况,但我做不到。无论我想尝试什么用户操作,都会调用我的 onViewCreated 方法并且我的变量是非 Null 的。也许我误读了堆栈跟踪。我希望下面的堆栈跟踪可以为大家提供足够的信息来帮助我,但如果没有,请告诉我关于该应用程序我还能告诉你什么。我无法 post 我的完整源代码(因为它不属于我),但我会尽我所能提供任何信息。
非常感谢您的帮助!
来自我的 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);
现在我想我明白了问题所在。
- 在 roboguice 中,视图被注入 onViewCreated()。
onViewCreated()
在onCreateView()
之后调用。bindLocation()
在onCreateView()
中调用。
因此,此时 roboguice 尚未注入视图。
请尝试在 onViewCreated()
调用 super
后调用 bindLocation()
。
这就是我解决这个问题的方法。当你使用 ButterKnife 时。 如果没有这些配置,ButterKnife 会抛出 NPE。
在你使用这个库之前你必须做一些配置 ButterKnife Eclipse Configuration 或者 ButterKnife Android Studio Configuration
如果您正在使用 ADT 并且缺少 Annototion Processing 检查此以安装 Android Eclipse - Cannot see annotation processing option