应用程序在某些随机设备上崩溃
App crashing on some random devices
今天我在我的应用程序中遇到了一个奇怪的问题。所以在第一个 activity 中,有一个导航抽屉,其中一些项目列在列表视图中(在抽屉中)。导航抽屉中有滚动条。现在,在一些随机设备上出现问题。应用程序正常启动,但只要我滚动(内部导航抽屉),应用程序就会崩溃。 Eclipse 抛出 NullPointer 异常。我不明白,因为问题发生在某些设备上,但在其他设备上却完美无缺。
我正在 posting logcat 以及其他相关文件。
Logcat:
02-16 18:54:46.879: E/AndroidRuntime(1654): FATAL EXCEPTION: main
02-16 18:54:46.879: E/AndroidRuntime(1654): Process: com.example.passpass, PID: 1654
02-16 18:54:46.879: E/AndroidRuntime(1654): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.example.passpass.adapter.NavDrawerListAdapter.getView(NavDrawerListAdapter.java:89)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.obtainView(AbsListView.java:2344)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.makeAndAddView(ListView.java:1864)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.fillDown(ListView.java:698)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.fillGap(ListView.java:662)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4968)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3398)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.onTouchMove(AbsListView.java:3774)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3612)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.View.dispatchTouchEvent(View.java:8388)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2424)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2158)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2314)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1692)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.app.Activity.dispatchTouchEvent(Activity.java:2739)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2275)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.View.dispatchPointerEvent(View.java:8578)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4021)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3887)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5701)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5675)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5646)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5791)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5762)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5814)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer.doCallbacks(Choreographer.java:580)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer.doFrame(Choreographer.java:548)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
02-16 18:54:46.879: E/AndroidRuntime(1654): at
Adapter 的 Getview 方法 Logcat 正在讨论
public class NavDrawerListAdapter 扩展了 BaseAdapter {
private Context context;
private ArrayList<Category> navDrawerItems;
public NavDrawerListAdapter(Context context, ArrayList<Category> navDrawerItems){
this.context = context;
this.navDrawerItems = navDrawerItems;
}
@Override
public int getCount() {
return navDrawerItems.size();
}
@Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
int type=3;
if(navDrawerItems.get(position).getId()==0)
type=0;
else if(navDrawerItems.get(position).getId()==10)
type=10;
else
type=1;
return type;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
if(type==0)
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
txtTitle.setText(navDrawerItems.get(position).getName());
}
else if(type==1)
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item_sub, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
txtTitle.setText(navDrawerItems.get(position).getName()); //Eclipse is throwing NPE here
}
else
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.home, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.home);
txtTitle.setText(navDrawerItems.get(position).getName());
}
return convertView;
}
}
XML 文件:这是我用于导航抽屉的不同行的三种布局之一。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/list_selector">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="55dp"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="@color/list_item_title"
android:gravity="center_vertical"
android:paddingRight="40dp"
android:textSize="10dp"/>
</RelativeLayout>
导致问题的原因是什么?请告诉我是否需要我 post 导航抽屉代码或布局文件。
提前致谢
您似乎使用了三种不同的物品类型,而且您很尊重 convertView
。这意味着 OS 给你的布局可能与你期望的不同,因为它正在被回收。例如,您可能会返回 home
布局,但它似乎没有 title
视图。
要纠正这个问题,您要么需要跟踪您扩充了哪种类型的布局,例如,通过添加 tag
and/or viewholder 模式;或者您需要忽略回收视图并始终膨胀视图。
今天我在我的应用程序中遇到了一个奇怪的问题。所以在第一个 activity 中,有一个导航抽屉,其中一些项目列在列表视图中(在抽屉中)。导航抽屉中有滚动条。现在,在一些随机设备上出现问题。应用程序正常启动,但只要我滚动(内部导航抽屉),应用程序就会崩溃。 Eclipse 抛出 NullPointer 异常。我不明白,因为问题发生在某些设备上,但在其他设备上却完美无缺。 我正在 posting logcat 以及其他相关文件。
Logcat:
02-16 18:54:46.879: E/AndroidRuntime(1654): FATAL EXCEPTION: main
02-16 18:54:46.879: E/AndroidRuntime(1654): Process: com.example.passpass, PID: 1654
02-16 18:54:46.879: E/AndroidRuntime(1654): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.example.passpass.adapter.NavDrawerListAdapter.getView(NavDrawerListAdapter.java:89)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.obtainView(AbsListView.java:2344)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.makeAndAddView(ListView.java:1864)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.fillDown(ListView.java:698)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.ListView.fillGap(ListView.java:662)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4968)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3398)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.onTouchMove(AbsListView.java:3774)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3612)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.View.dispatchTouchEvent(View.java:8388)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2424)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2158)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2430)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2172)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2314)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1692)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.app.Activity.dispatchTouchEvent(Activity.java:2739)
02-16 18:54:46.879: E/AndroidRuntime(1654): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2275)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.View.dispatchPointerEvent(View.java:8578)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4021)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3887)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5701)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5675)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5646)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5791)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5762)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5814)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer.doCallbacks(Choreographer.java:580)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer.doFrame(Choreographer.java:548)
02-16 18:54:46.879: E/AndroidRuntime(1654): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
02-16 18:54:46.879: E/AndroidRuntime(1654): at
Adapter 的 Getview 方法 Logcat 正在讨论
public class NavDrawerListAdapter 扩展了 BaseAdapter {
private Context context;
private ArrayList<Category> navDrawerItems;
public NavDrawerListAdapter(Context context, ArrayList<Category> navDrawerItems){
this.context = context;
this.navDrawerItems = navDrawerItems;
}
@Override
public int getCount() {
return navDrawerItems.size();
}
@Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
int type=3;
if(navDrawerItems.get(position).getId()==0)
type=0;
else if(navDrawerItems.get(position).getId()==10)
type=10;
else
type=1;
return type;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
if(type==0)
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
txtTitle.setText(navDrawerItems.get(position).getName());
}
else if(type==1)
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item_sub, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
txtTitle.setText(navDrawerItems.get(position).getName()); //Eclipse is throwing NPE here
}
else
{
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.home, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.home);
txtTitle.setText(navDrawerItems.get(position).getName());
}
return convertView;
}
}
XML 文件:这是我用于导航抽屉的不同行的三种布局之一。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/list_selector">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="55dp"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="@color/list_item_title"
android:gravity="center_vertical"
android:paddingRight="40dp"
android:textSize="10dp"/>
</RelativeLayout>
导致问题的原因是什么?请告诉我是否需要我 post 导航抽屉代码或布局文件。
提前致谢
您似乎使用了三种不同的物品类型,而且您很尊重 convertView
。这意味着 OS 给你的布局可能与你期望的不同,因为它正在被回收。例如,您可能会返回 home
布局,但它似乎没有 title
视图。
要纠正这个问题,您要么需要跟踪您扩充了哪种类型的布局,例如,通过添加 tag
and/or viewholder 模式;或者您需要忽略回收视图并始终膨胀视图。