Skip to main content
 首页 » 编程设计

android之意外的生命周期导致致命异常

2025年05月04日10myhome

我是一名 iOS 开发人员,完全没有使用 android 的经验,所以如果我难以表达我的问题,请原谅我:

我在负责维护的 android 应用程序中遇到致命异常。

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

我可以从崩溃报告(附在下面)中看到,崩溃发生在我的一个 fragment 中的一个名为“bindLocation”的方法中

这是它崩溃的行:
            mLocationHeaderTextView.setVisibility(View.VISIBLE); 

很明显,问题在于 mLocationHeaderTextview 为空。 mLocationHeaderTextView 使用 roboguice 注入(inject)如下:
 @InjectView(R.id.filter_location_header) 
TextView mLocationHeaderTextView; 

现在,我认为该错误是由于我的 textView 没有被“注入(inject)”引起的。查看堆栈跟踪后,我确定这可能是 onViewCreated() 在调用 bindLocation() 之前没有被调用的结果。

然而,这就是我迷路的地方。我对android非常不熟悉,所以我不确定我的onViewCreated方法怎么可能被跳过。我已经在设备上尝试了一百万种方法来尝试重现这种情况,但我做不到。无论我想尝试什么用户操作,我的 onViewCreated 方法都会被调用,并且我的变量是非 Null。也许我误读了堆栈跟踪。我希望我下面的堆栈跟踪为你们提供了足够的信息来帮助我,但如果没有,请告诉我关于该应用程序我还能告诉你什么。我不能发布我的完整源代码(因为它不属于我),但我会提供我能提供的任何信息。

非常感谢你的帮助!



从我的 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()
位置查找器 fragment :
 @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 View 中注入(inject) onViewCreated() .
  • onViewCreated()onCreateView() 之后调用.
  • bindLocation()onCreateView() 中调用.

  • 因此,到这个时候,roboguice 还没有注入(inject) View 。

    请尝试调用 bindLocation()onViewCreated()调用 super 后.