it-swarm.com.ru

Сбой в ListView на AbsListView.obtainView для ListActivity

Я наблюдаю за обновлениями содержимого ListActivity с помощью ContentObserver следующим образом:

protected void onCreate(Bundle savedState)
   {
        super.onCreate(savedState);

        ContentResolver cr = getContentResolver();

        Cursor cursor = cr.query(TrackHeader.CONTENT_URI, sTrackListProjection, null, null, null);
        startManagingCursor(cursor);

        this.mAdapter = new TrackHeaderDataAdapter(this, R.layout.track_list_item, cursor, sTrackListProjection, null);
        setListAdapter(mAdapter);

        Handler handler = new Handler();

        mTrackHeaderObserver = new ContentObserver(handler) {

             @Override 
             public boolean deliverSelfNotifications() { 
                 return false;
             }

             @Override
             public void onChange(boolean selfChange) {
                 super.onChange(selfChange);
                 ContentResolver cr = getContentResolver();
                 mAdapter.changeCursor(cr.query(TrackHeader.CONTENT_URI, sTrackListProjection, null, null, null));
              }
         };

      getContentResolver().registerContentObserver (TrackHeader.CONTENT_URI, true, mTrackHeaderObserver);
  }

Этот обозреватель контента, кажется, в порядке - он вызывается обратно в потоке пользовательского интерфейса, но я довольно неожиданно получаю следующее случайное падение в базовом ListView:

02-21 14:06:00.440: ERROR/AndroidRuntime(739): Java.lang.NullPointerException
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at  Android.widget.AbsListView.obtainView(AbsListView.Java:1276)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.ListView.makeAndAddView(ListView.Java:1668)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.ListView.fillDown(ListView.Java:637)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.ListView.fillSpecific(ListView.Java:1224)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.ListView.layoutChildren(ListView.Java:1499)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.AbsListView.onLayout(AbsListView.Java:1113)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1119)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:998)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.LinearLayout.onLayout(LinearLayout.Java:918)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.widget.FrameLayout.onLayout(FrameLayout.Java:333)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.View.layout(View.Java:6830)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.ViewRoot.performTraversals(ViewRoot.Java:996)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.view.ViewRoot.handleMessage(ViewRoot.Java:1633)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.os.Handler.dispatchMessage(Handler.Java:99)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.os.Looper.loop(Looper.Java:123)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Android.app.ActivityThread.main(ActivityThread.Java:4363)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Java.lang.reflect.Method.invokeNative(Native Method)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at Java.lang.reflect.Method.invoke(Method.Java:521)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:860)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618)
02-21 14:06:00.440: ERROR/AndroidRuntime(739):     at dalvik.system.NativeStart.main(Native Method)
02-21 14:09:56.159: ERROR/AndroidRuntime(749): ERROR: thread attach failed
02-21 14:09:59.480: ERROR/AndroidRuntime(760): ERROR: thread attach failed
02-21 14:12:19.449: ERROR/AndroidRuntime(778): ERROR: thread attach failed
02-21 14:12:22.779: ERROR/AndroidRuntime(789): ERROR: thread attach failed
02-21 14:12:26.479: ERROR/gralloc(51): [unregister] handle 0x3f13b8 still locked (state=40000001)

Кто-нибудь видел что-то подобное раньше - был на этом замешан в течение нескольких дней ...

Тим

56
Tim

У меня была похожая трассировка стека, и я обнаружил, что в некоторых случаях я возвращал нуль из метода getView ().

229
jonny99

Если у вас есть список и вы можете расширить BaseAdapter или Adapter, чтобы получить пользовательский список, убедитесь, что getView возвращает ненулевое значение.

Если у вас есть представление с вкладками, и один из ваших фрагментов является списком, который переопределяет Adapter/BaseAdapter и getView возвращает null, вы получите эту проблему.

11
Skywalker

Если вы используете статический класс ViewHolder для хранения элементов представления в адаптере, вы можете забыть установить объект viewHolder в качестве тега convertView. Например:

if (convertView == null) {
    LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        convertView = mInflater.inflate(R.layout.adapter_drivers_and_riders, null);
        holder = new ViewHolder();
        holder.tvDate = (TextView)convertView.findViewById(R.id.tvDate);
        holder.tvTime = (TextView)convertView.findViewById(R.id.tvTime);

        convertView.setTag(holder);

} else {
    holder = (ViewHolder) convertView.getTag();
}

В моем случае я не использовал Курсор, но имел ту же проблему, я понял, что я забыл установить тег как viewHolder для convertView, поэтому, когда создаются первые представления адаптера для списка, это нормально, но когда вы прокручиваете и механизм утилизации работает, он выходит из строя, так как он не может восстановить viewHolder из convertView.

На всякий случай я хотел упомянуть.

4
Merve Gencer

Я не использовал changeCursor(). И, поскольку запрос, который вы использовали для создания Cursor, совпадает с запросом, который вы используете для "изменения" курсора, я бы сразу бросил вызов changeCursor() и просто вызвал requery() для имеющегося у вас Cursor.

3
CommonsWare