Android StackOverflowError в ViewGroup.resetResolvedTextDirection при добавлении ListView в LinearLayout - PullRequest
3 голосов
/ 23 февраля 2012

Ранее я задавал один вопрос об этой ошибке ( Android StackOverflowError в ViewGroup.resetResolvedTextDirection ), однако теперь мне удалось воспроизвести ошибку в эмуляторе и сузил конкретное место, где возникает эта проблема.

Когда я начинаю свою деятельность, у меня есть AsyncTask, который извлекает необходимые данные с моего сервера и создает все представления.Внутри run() метода AsyncTask я создаю собственное представление (и добавляю его в основной вид действия - но это сейчас не важно):

ListingView listing = new ListingView(MainActivity.this);

ListingView - это моепользовательский класс представления, который расширяется от LinearLayout.В конструкторе этого пользовательского представления у меня есть следующий код:

public ListingView(Context context)
{
    this.context = context;
    ...

    LayoutInflater infl = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View top = infl.inflate(R.layout.listing, this, true);
    this.addView(top);
    ...

    LinearLayout lst = (LinearLayout)this.findViewById(R.id.LayoutListingTop);
    tblVenues = new ListView(context);
    tblVenues.setVisibility(VISIBLE);
    tblVenues.setItemsCanFocus(true);
    tblVenues.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if(venueListener != null && venues.size() > 0) { venueListener.selected(venues.get(position)); }
        }
    });
    LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    lst.addView(tblVenues, lp);    //this line causes the problem

    ...
}

В этом пользовательском классе представления tblVenues объявлен как

private ListView tblVenues;

И загружаемый XMLthis:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:id="@+id/LayoutListingTop"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@color/white">
    <ImageView android:id="@+id/ImageView01"
               android:layout_width="170dp"
               android:layout_height="62dp"
               android:src="@drawable/ookl_logo"
               android:layout_gravity="left"
               android:adjustViewBounds="false"
               android:scaleType="fitXY">
    </ImageView>

    <TextView android:layout_height="wrap_content"
              android:layout_width="fill_parent"
              android:layout_marginBottom="5px"
              android:gravity="center"
              android:textColor="@color/black"
              android:text="@string/love_culture"
              android:id="@+id/TextView01"
              android:textSize="28dip">
    </TextView>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="horizontal"
                  android:id="@+id/ButtonBar"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:background="@drawable/buttonbar"
                  android:paddingLeft="10px"
                  android:paddingRight="10px"
                  android:paddingTop="5px"
                  android:paddingBottom="5px">

        <Button android:id="@+id/BtnListVenues"
                     android:layout_width="wrap_content"
                     android:layout_height="45dip"
                     android:background="@null"
                     android:text="@string/button_venues"
                     android:drawableTop="@drawable/icon_venues_on"
                     android:textColor="@color/venue_blue"
                     android:layout_marginRight="10px"
                     android:textSize="9dip">
        </Button>

        <Button android:id="@+id/BtnListEvents"
                     android:layout_width="wrap_content"
                     android:layout_height="45dip"
                     android:background="@null"
                     android:text="@string/button_events"
                     android:drawableTop="@drawable/icon_events_off"
                     android:textColor="@color/white"
                     android:layout_marginRight="10px"
                     android:textSize="9dip">
        </Button>

        <Button android:id="@+id/BtnListTrails"
                     android:layout_width="wrap_content"
                     android:layout_height="45dip"
                     android:background="@null"
                     android:text="@string/button_trails"
                     android:drawableTop="@drawable/icon_trails_off"
                     android:textColor="@color/white"
                     android:layout_marginRight="10px"
                     android:textSize="9dip">
        </Button>

        <Button android:id="@+id/BtnListObjects"
                     android:layout_width="wrap_content"
                     android:layout_height="45dip"
                     android:background="@null"
                     android:text="@string/button_objects"
                     android:drawableTop="@drawable/icon_objects_off"
                     android:textColor="@color/white"
                     android:layout_marginRight="10px"
                     android:textSize="9dip">
        </Button>

        <TextView android:id="@+id/TxtLabelDistance"
                  android:layout_width="fill_parent"
                  android:text="@string/label_distance"
                  android:layout_height="wrap_content"
                  android:gravity="right|bottom"
                  android:layout_alignParentBottom="true"
                  android:textColor="@color/white"
                  android:layout_marginTop="-17px"
                  android:textSize="9dip">
        </TextView>
    </LinearLayout>


</LinearLayout>

Все это прекрасно работает на Android от 1.6 до 3.x, однако на линии Ice Cream Sandwich (4.0)

lst.addView(tblVenues, lp);

приводит к StackOverflowError:

java.lang.StackOverflowError
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
at android.view.ViewGroup.resetResolvedTextDirection(ViewGroup.java:5131)
... this line repeats about 200 times or so ...

В LogCat больше нет ничего полезного.Весь ListingView еще даже не добавлен к основному виду активности, потому что ошибка, по сути, выдается из его конструктора.

Я полностью теряюсь в том, в чем может быть проблема.Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

5 голосов
/ 27 мая 2013

[Старый вопрос, но я не был удовлетворен ответом, поэтому добавляю свои заметки в надежде, что они будут полезны для кого-то еще.]

Алекс - Я согласен, что основной проблемой является ошибка Android, но при трассировке кода (недавно я столкнулся с подобной проблемой), я считаю, что эту проблему можно предотвратить, если для параметра attachToRoot установить значение false. Это связано с тем, что с attacheToRoot == true возвращаемое представление является параметром 'root', который вы передали. В вашем случае это 'this', который затем добавляет дочерний элемент текущего представления (вы добавляете объект как дочерний объект). само по себе). Это, кажется, сбивает с толку андроида (это действительно должно проверить на равенство экземпляров).

http://developer.android.com/reference/android/view/LayoutInflater.html#inflate(org.xmlpull.v1.XmlPullParser, android.view.ViewGroup, логическое значение)

"[Возвращает] Корневое представление завышенной иерархии. Если указан корень и attachToRoot имеет значение true, это корень; в противном случае это корень завышенного XML-файла ."

Внесение этого изменения решило проблему в моем случае.

3 голосов
/ 08 июня 2014

Обновление : На самом деле это плохой совет, который я выучил с помощью API на протяжении многих лет. Смотрите топ проголосовавших ответ. Вы должны добавить родительское представление, даже если это трудно получить. Я полагаю, это потому, что параметры layout_ в вашем корневом элементе из завышенного XML зависят от родительского макета. Например, layout_below (или что-то подобное) доступно, если ваш элемент является дочерним по отношению к RelativeLayout. По крайней мере, у меня возникли проблемы, когда я прошел null в.

Я отлаживал сам Android, потому что сделал ту же ошибку и нашел реальную причину. Настоящая проблема заключается в этих строках:

View top = infl.inflate(R.layout.listing, this, true);
this.addView(top);

Как видите, вы передаете this в качестве второго параметра inflate, который уже добавляет раздутое представление к this, поэтому, когда вы делаете this.addView(top), оно добавляется еще раз. У вас есть два варианта исправления ошибки: удалить строку this.addView(top) или заменить this на null. Я не пробовал второй вариант, но он также должен работать и, вероятно, является лучшим решением, если вы хотите манипулировать представлениями перед добавлением к родителю после инфляции.

Параметр attachToRoot, упомянутый BigDSK, может быть достаточным, но я считаю, что пропуск null и добавление addViewing после этого или пропуск addView является более пуленепробиваемым решением (IMHO), поэтому я решил поделиться .

2 голосов
/ 24 февраля 2012

После того, как я довольно долго бился головой о стену и пробовал всевозможные подходы, я считаю, что это действительно ошибка в андроиде, которая проявляется, когда для visibility View явно установлено значение VISIBLEно само представление и его родительский вид не добавляются к основному виду.

Наконец-то я обошел его, добавив ListView в XML и переместив код setVisibility(View.VISIBLE) после добавления всего представления к основному.view (т.е. родительскую иерархию можно проследить от каждого потомка до самого конца).

По крайней мере, я больше не получаю эту ошибку.

...