2012-11-23 26 views
1

我的Android项目中出现奇怪的错误。有时,应用程序崩溃与此IllegalStateException异常:由RelativeLayout中的循环依赖造成的奇怪的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); 
} 

是否有人已经遇到这样的事情?任何帮助非常感谢...

+0

用一个'View'从左边试试。如果有效,请尝试使用左侧的两个“视图”。然后尝试从左侧和右侧的一个“视图”等,然后我相信你会发现问题。 –

+0

@DmitryZaitsev谢谢,我会尝试。我应该提到,当我首先开始活动时,布局工作正常,但在从其他活动返回后崩溃。问题必须在某处... –

+1

感谢您的所有答案!仍然不确定,是什么导致了错误。不过,我通过在重新开始活动之前从布局中删除所有视图来解决此问题。也许一些观点留在记忆中,然后我试图将它们添加到他们自己旁边...... –

回答

2

在logcat中打印出你的ID,对于你动态添加的所有视图,你一定会找到一个定义你的布局的循环依赖的视图。你的代码不容易遵循,但你的错误在那里。