I am building an Android app using a pile of switch statements to switch between views. Everything was going fine until I added a block of cases that cause a fatal error when the app is starting up. The cases are called by onClick statements in the XML. The offending block of cases is actually part of a block of statements that work fine. Can anyone see what I'm missing? What's causing the fatal error? I'm including snippets of the broken code and working code along with the logCat file.
05-17 01:48:01.931: INFO/System.out(270): debugger has settled (1381)
05-17 01:48:02.341: WARN/dalvikvm(270): VFY: invalid switch target 7170 (-> 0x1c0b) at 0x9[0]
05-17 01:48:02.351: WARN/dalvikvm(270): VFY: rejected Lcom/findthway/main;.nextLayout (Landroid/view/View;)V
05-17 01:48:02.351: WARN/dalvikvm(270): Verifier rejected class Lcom/findthway/main;
05-17 01:48:02.351: WARN/dalvikvm(270): Class init failed in newInstance call (Lcom/findthway/main;)
05-17 01:48:03.031: INFO/ActivityManager(67): Displayed activity com.android.launcher/com.android.launcher2.Launcher: 50893 ms (total 50893 ms)
05-17 01:48:08.001: WARN/ActivityManager(67): Launch timeout has expired, giving up wake lock!
05-17 01:48:08.751: WARN/ActivityManager(67): Activity idle timeout for HistoryRecord{43eda500 com.findthway/.main}
05-17 01:52:41.531: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 01:57:41.551: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:02:41.576: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:07:41.641: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:08:45.831: DEBUG/dalvikvm(67): GC_FOR_MALLOC freed 15592 objects / 665856 bytes in 160ms
05-17 02:12:41.695: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:16:30.392: DEBUG/dalvikvm(67): GC_FOR_MALLOC freed 4697 objects / 200928 bytes in 108ms
05-17 02:17:41.716: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:22:41.745: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:27:41.801: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:32:41.812: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:37:41.851: DEBUG/SntpClient(67): request time failed: java.net.SocketException: Address family not supported by protocol
05-17 02:41:00.341: DEBUG/dalvikvm(67): GC_FOR_MALLOC freed 12690 objects / 520224 bytes in 235ms
Example of the XML that would be calling the broken switch cases:
<RelativeLayout android:id="@+id/level07_layout00"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/vlayoutup"
android:visibility="gone">
<ImageButton android:id="@+id/level07_closeButton00"
android:layout_height="wrap_content"
android:background="@drawable/close"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:onClick="closetomain">
</ImageButton>
<ImageButton android:id="@+id/level07_leftButton00"
android:layout_height="wrap_content"
android:background="@drawable/node"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_marginLeft="135dp"
android:onClick="nextLayout">
</ImageButton>
<ImageButton android:id="@+id/level07_rightButton00"
android:layout_height="wrap_content"
android:background="@drawable/node"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_marginLeft="340dp"
android:onClick="nextLayout">
</ImageButton>
<ImageView android:id="@+id/level07_beginButton00"
android:layout_height="wrap_content"
android:background="@drawable/beginbutton"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="2dp"
android:layout_marginLeft="235dp">
</ImageView>
<ImageView android:id="@+id/level07_ImageView00"
android:layout_height="wrap_content"
android:layout_widt开发者_JS百科h="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="325dp"
android:background="@drawable/rocket">
</ImageView>
</RelativeLayout>
<RelativeLayout android:id="@+id/level07_layout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/vlayoutup"
android:visibility="gone">
<ImageButton android:id="@+id/level07_closeButton01"
android:layout_height="wrap_content"
android:background="@drawable/close"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:onClick="closetomain">
</ImageButton>
<ImageButton android:id="@+id/level07_leftButton01"
android:layout_height="wrap_content"
android:background="@drawable/node"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_marginLeft="135dp"
android:onClick="nextLayout">
</ImageButton>
<ImageButton android:id="@+id/level07_rightButton01"
android:layout_height="wrap_content"
android:background="@drawable/node"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_marginLeft="340dp"
android:onClick="nextLayout">
</ImageButton>
<ImageButton android:id="@+id/level07_backButton01"
android:layout_height="wrap_content"
android:background="@drawable/backlevel"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="2dp"
android:layout_marginLeft="235dp"
android:onClick="prevLayout">
</ImageButton>
</RelativeLayout>
Here's a snippet of the broken java:
case R.id.level07_backButton01:
RelativeLayout bB017 = (RelativeLayout)findViewById(R.id.level07_layout00);
bB017.setVisibility(View.VISIBLE);
RelativeLayout bB017b = (RelativeLayout)findViewById(R.id.level07_layout01);
bB017b.setVisibility(View.GONE);
break;
case R.id.level07_backButton02:
RelativeLayout bB027b = (RelativeLayout)findViewById(R.id.level07_layout01);
bB027b.setVisibility(View.VISIBLE);
RelativeLayout bB027 = (RelativeLayout)findViewById(R.id.level07_layout02);
bB027.setVisibility(View.GONE);
break;
case R.id.level07_backButton03:
RelativeLayout bB037 = (RelativeLayout)findViewById(R.id.level07_layout02);
bB037.setVisibility(View.VISIBLE);
RelativeLayout bB037b = (RelativeLayout)findViewById(R.id.level07_layout03);
bB037b.setVisibility(View.GONE);
break;
Here's a snippet of the code that works from the same block:
case R.id.level07_backButton16:
RelativeLayout bB167 = (RelativeLayout)findViewById(R.id.level07_layout15);
bB167.setVisibility(View.VISIBLE);
RelativeLayout bB167b = (RelativeLayout)findViewById(R.id.level07_layout16);
bB167b.setVisibility(View.GONE);
break;
case R.id.level07_backButton17:
RelativeLayout bB177 = (RelativeLayout)findViewById(R.id.level07_layout13);
bB177.setVisibility(View.VISIBLE);
RelativeLayout bB177b = (RelativeLayout)findViewById(R.id.level07_layout17);
bB177b.setVisibility(View.GONE);
break;
case R.id.level07_backButton18:
RelativeLayout bB187 = (RelativeLayout)findViewById(R.id.level07_layout17);
bB187.setVisibility(View.VISIBLE);
RelativeLayout bB187b = (RelativeLayout)findViewById(R.id.level07_layout18);
bB187b.setVisibility(View.GONE);
break;
As you can see, I think, the two blocks of switch cases are the same. The part that I think is the important clue is in the logCat: VFY: invalid switch target.
If you need more information please let me know. Thanks in advance for the help!
Use a default case to trap unspecified cases, however it's not required.
Check the switch statement.
How large is the method? What version of Android?
There was a bug in <= 2.2 ("Froyo") where the bytecode verifier was only looking at the low 16 bits of an offset value for switch data, so it was incorrectly rejecting some larger methods. See http://code.google.com/p/android/issues/detail?id=11552 .
I can't guarantee that it's the same problem without seeing the code, but it sounds similar. You can check the size of the method by running "dexdump" on the APK and searching for the method.
It turned out that there were too many cases in the switch statement. I didn't know there was a limit, but I guess there is. I broke the switch statements into separate methods and that did the trick. Thanks everyone for your suggestions!
精彩评论