我之前已经问了一个关于此错误的问题(Android StackOverflowError in ViewGroup.resetResolvedTextDirection),但是现在我设法在模拟器中重现错误并缩小发生此问题的具体位置。
当我开始活动时,我有一个AsyncTask
,它从我的服务器中提取必要的数据并创建所有视图。在AsyncTask的run()
方法中,我正在创建一个自定义视图(并将其添加到活动的主视图中 - 但现在这并不重要):
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;
正在加载的XML是:
<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上完全正常,但在冰淇淋三明治(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甚至还没有添加到主活动视图中,因为错误主要是从它的构造函数中抛出的。
我完全不知道可能是什么问题。任何帮助将不胜感激。
答案 0 :(得分:5)
[老问题,但我对答案不满意,所以添加我的笔记,希望它们对别人有帮助。]
Aleks - 我同意核心问题是Android漏洞,但是跟踪代码(我最近遇到过类似的问题)我相信通过将attachToRoot参数设置为false来防止这个问题。这是因为使用attacheToRoot == true,返回的视图是您传入的“root”参数。在您的情况下是'this',然后添加当前视图的子项(您将对象添加为子项)本身)。这似乎混淆了android(它确实应该检查实例的相等性)。
“[返回]膨胀层次结构的根视图。如果提供了root并且attachToRoot为true,则为root;否则它是膨胀的XML文件的根。”
进行此更改解决了我的问题。
答案 1 :(得分:3)
更新:这实际上是一个糟糕的建议,我多年来一直使用API学习。见最高投票回答。您必须添加父视图,即使它很难获得。我相信这是因为来自膨胀的XML的根元素中的layout_
参数取决于父布局。例如,如果您的元素是layout_below
的子元素,则可以使用RelativeLayout
(或类似的东西)。当我通过null
时,至少我遇到了相关的问题。
我正在调试Android本身,因为我犯了同样的错误,我发现了真正的原因。真正的问题在于以下几个方面:
View top = infl.inflate(R.layout.listing, this, true);
this.addView(top);
正如您所看到的,您将this
作为膨胀的第二个参数传递,它已将膨胀的视图添加到this
,因此当您执行this.addView(top)
时,它会再添加一个时间。您有两种方法可以纠正这样的错误:删除行this.addView(top)
,或将this
替换为null
。我还没有尝试过第二个问题,但是如果你想在通货膨胀之后加入父母之前操纵视图,那么它应该也可以运行,并且可能是一个更好的解决方案。
BigDSK提到的attachToRoot
参数可能就足够了,但我发现传递null
和之后的addViewing,或省略addView
是一个更加防弹的解决方案(恕我直言),所以我想我会分享。
答案 2 :(得分:2)
在我的头撞墙后尝试各种不同的方法后,我相信,这真的是一个机器人中的一个错误,当一个视图的visibility
被明确设置为{ {1}}但视图本身和视图的父级未添加到主视图中。
我终于通过将ListView添加到XML并将代码VISIBLE
移动到整个视图添加到主视图之后(即父级层次结构可以从每个子级一直追溯到结束)来解决它)。
至少我不会再出现这个错误了。