我在我的 Android 项目中遇到了一个奇怪的错误。有时应用程序会因此 IllegalStateException 而崩溃:
11-23 08:20:51.610: E/AndroidRuntime(16714): FATAL EXCEPTION: main
11-23 08:20:51.610: E/AndroidRuntime(16714): java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout$DependencyGraph.getSortedViews(RelativeLayout.java:1286)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout.sortChildren(RelativeLayout.java:294)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:314)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1385)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureVertical(LinearLayout.java:670)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.measureVertical(LinearLayout.java:822)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2240)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.View.measure(View.java:12775)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1117)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2505)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.os.Handler.dispatchMessage(Handler.java:99)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.os.Looper.loop(Looper.java:137)
11-23 08:20:51.610: E/AndroidRuntime(16714): at android.app.ActivityThread.main(ActivityThread.java:4514)
11-23 08:20:51.610: E/AndroidRuntime(16714): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 08:20:51.610: E/AndroidRuntime(16714): at java.lang.reflect.Method.invoke(Method.java:511)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
11-23 08:20:51.610: E/AndroidRuntime(16714): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
11-23 08:20:51.610: E/AndroidRuntime(16714): at dalvik.system.NativeStart.main(Native Method)
我知道这应该是由 RelativeLayout 中的两个小部件相互引用引起的,但这里绝对不是这种情况。我在这个布局文件中使用了一个 RelativeLayout(在底部):
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="450dp" >
<fragment
android:id="@+id/identification_navigation_fragment"
android:name="plt.demonstrator.common.NavigationFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:id="@+id/view1"
android:layout_width="3dp"
android:layout_height="match_parent"
android:layout_weight="0"
android:background="@color/lightgray" />
<fragment
android:id="@+id/identification_fragment"
android:name="plt.demonstrator.identifikation.IdentificationFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3.5" />
</LinearLayout>
<RelativeLayout
android:id="@+id/bottom_actionbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:background="#DDDDDD" >
</RelativeLayout>
项目在运行时动态添加,无论是在左侧还是右侧。所以实际上左侧的任何项目都没有引用右侧的东西,反之亦然。此外,我无法识别导致此异常的代码的任何部分,调试器运行直到onResume()
完成并且应用程序处于恢复状态。这是添加项目的代码,但正如我所说,调试器不会对此提出异议......
public static void addActionbarItem(RelativeLayout actionbar, Context ctx, int itemid, int textid,
int iconid, Direction direction, View.OnClickListener listener) {
TextView item = new TextView(ctx);
item.setText(ctx.getString(textid).toUpperCase());
item.setTextAppearance(ctx, android.R.style.TextAppearance_Medium);
int paddingPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, ctx.getResources().getDisplayMetrics());
item.setPadding(paddingPx, 0, paddingPx, 0);
item.setGravity(Gravity.CENTER_VERTICAL);
item.setId(itemid);
Drawable icon = ctx.getResources().getDrawable(iconid);
icon.setBounds(0, 0, 24, 24);
item.setCompoundDrawables(icon, null, null, null);
RelativeLayout.LayoutParams separatorParams = new LayoutParams(1, 32);
// vertical separator
View separator = new View(ctx);
int color = ctx.getResources().getColor(android.R.color.secondary_text_light);
separator.setBackgroundColor(color);
separator.setId(separatorId++);
separatorParams.setMargins(0, 8, 0, 0);
RelativeLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (direction == Direction.LEFT) {
// Item should be added at left side
if (leftAnchor != -1) {
// There is already an item at left side -> place the new item right to it
separatorParams.addRule(RelativeLayout.RIGHT_OF, leftAnchor);
separator.setLayoutParams(separatorParams);
actionbar.addView(separator);
params.addRule(RelativeLayout.RIGHT_OF, separator.getId());
} else {
// Item is the first on left side, place it at left edge
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, -1);
// Add some space to the display edge
params.setMargins(8, 0, 0, 0);
}
// Update anchor ID
leftAnchor = itemid;
} else {
// Item should be added at right side
if (rightAnchor != -1) {
// There is already an item at right side -> place the new item left to it
separatorParams.addRule(RelativeLayout.LEFT_OF, rightAnchor);
separator.setLayoutParams(separatorParams);
actionbar.addView(separator);
params.addRule(RelativeLayout.LEFT_OF, rightAnchor);
} else {
// Item is the first on right side, place it at right edge
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, -1);
// Add some space to the display edge
params.setMargins(0, 0, 8, 0);
}
// Update anchor ID
rightAnchor = itemid;
}
item.setLayoutParams(params);
// Set item behaviour
item.setOnClickListener(listener);
// Add a touch listener for visual feedback
// Touch listener is invoked before click listener, so event must be forwarded after onTouch method
item.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(final View v, MotionEvent e) {
// ICS clicked button style
v.setBackgroundColor(0x880099CC);
v.invalidate();
Runnable timer = new Runnable() {
public void run() {
// Reset color
v.setBackgroundColor(Color.TRANSPARENT);
v.invalidate();
}
};
Handler h = new Handler();
h.removeCallbacks(timer);
// Reset button style after 50ms
h.postDelayed(timer, 50);
// Forward event to OnClickListener
return false;
}
});
actionbar.addView(item);
}
有没有人遇到过这样的事情?任何帮助是极大的赞赏...