Occasionally gets null from (View).findViewByID
-
11-03-2021 - |
Question
I hava a Android app @ Android Market. And Im keep getting some crash reports that claims that some users get a NullPointerException.
I've located the code that seems to be causing this problem.
It's in a ArrayAdapters getView method.
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.subcatategory_row, null);
holder = new ViewHolder();
v.setTag(holder);
}
else {
holder=(ViewHolder)v.getTag();
if(holder == null){
holder = new ViewHolder();
}
}
TextView tl = (TextView) v.findViewById(R.id.label);
tl.setTextAppearance(getContext(), R.style.styleA);
The last line in this snippet seems to be causing the crash. However I've never experienced it, and I've been testing it on several devices.
Help would be greatly appreciated!!
EDIT:
subcategory_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/row_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dip"
android:background="@drawable/background"
android:weightSum="80">
<TextView
android:id="@+id/label"
android:layout_weight="9"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_marginRight="6dip"
android:gravity="center_vertical|center"
android:text="C.r"
android:textSize="12sp"
android:textColor="@color/default_textcolor"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="53"
android:layout_height="fill_parent">
<TextView
android:id="@+id/text_bb"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_marginLeft="4dip"
android:gravity="bottom"
android:textSize="13sp"
android:textColor="@color/default_textcolor"
android:ellipsize="end" android:singleLine="true"/>
<TextView
android:id="@+id/text_ba"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_marginLeft="4dip"
android:gravity="top"
android:textSize="13sp"
android:textColor="@color/default_textcolor"
android:ellipsize="end" android:singleLine="true"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="8"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/text_a"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="bottom|right"
android:textSize="13sp"
android:text="0"
android:textColor="@color/default_textcolor"
/>
<TextView
android:id="@+id/text_b"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="top|right"
android:textSize="19sp"
android:text="0"
android:textColor="@color/default_textcolor"
/>
</LinearLayout>
<LinearLayout
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_weight="10"
android:orientation="vertical"
android:paddingLeft="10dp" >
<ImageView
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:paddingLeft="-10dip"
android:paddingRight="10dip"
android:src="@drawable/arrow"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
Solution
I also have had this issue on published apps. After a lot of soul searching I recreated it - in two different ways !
Reason 1 ) Turns out the reason it is null , is that there was no memory at the time to allocate it. Just had to write more protective code and shut down.
Reason 2 ) Dalvik in some cases got convinced that I was not using it and deallocated it. I had to alter my code to make sure it was more "hooked together" in Dalvik's eye.
However 9 times out of 10 , it was reason 1.
The problem is that you can't reproduce it as you are using test devices , other people have all sorts of stuff running at the same time.
OTHER TIPS
You should store the TextView
inside your ViewHolder object
Here's an example of something I've used
class DataObjectContainer {
TextView title;
}
public View getView(final Activity activity, View convertView, ViewGroup parent) {
final DataObjectContainer container;
if (convertView == null) {
convertView = (LinearLayout) activity.getLayoutInflater().inflate(R.layout.dataobjectitem, null);
container = new DataObjectContainer();
container.title = (TextView) convertView.findViewById(R.id.textview_title);
convertView.setTag(container);
} else {
container = ((DataObjectContainer) convertView.getTag());
}
container.title.setText(getValueString(DataObject.Table.NAME));
return convertView;
}