果冻豆运行设备(SPAN_EXCLUSIVE_EXCLUSIVE跨度不能有一个零长度)的Listactivity错误

我有应用程序开始与启动屏幕,然后打开列表活动行,单击任何行将打开一个活动,其中包含一个文本视图,两个button(其中之一打开一个无限的画廊,另一个打开自定义对话框)和菜单项, 出口)。

这个应用程序运行完美的姜面包,但在Galaxy S3运行果冻豆testing时,它正常打开,但是当你点击列表活动行之一,似乎忽略了点击。 日食上的日志显示:

SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 

然而,没有强制closures(列表活动正常滚动和菜单项工作正常)。

更新:
我注意到了这个应用程序的一些东西:我在一个月前用eclipse创build了一个叫做( trip )和今天testing( trip.apk )的姜面包和果冻豆,它的function非常完美。

但是我想改变trip的名字,我没有使用Refactor 。 相反,我创build了一个名为travel应用程序名称的新项目,但其他所有内容与之前的应用程序trip相同,包括类,res,以及使用果冻豆进行testing时显示的内容:

 SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 

更新3:

我解决了这个问题:

我将这行添加到我的应用程序中的所有TextView中:

  android:textIsSelectable="true" 

而那行会导致行忽略点击,

所以我删除它,现在新旧应用程序都适用于这两个API。

更新4:

以上的短语与老问题有关,已经解决了,

现在的问题是:

我的应用程序完全适用于所有的API,但在testing时:

银河S3运行果冻豆也完美的工作,

但在eclipse log cat中显示错误:

  SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 

而不影响应用程序性能,任何想法来解决这个错误。

任何解释将不胜感激,谢谢。

我的项目代码:

菜单:

 public class Menu extends ListActivity { String classes[] = { "Introduction", "DreamsTrip", "Day one", "Day Two", "Day Three", "Day Four", "Day Five", "Conclusion" }; @Override protected void onCreate(Bundle savedInstanceState) { this.requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); // create background for whole list as image ListView lv = getListView(); lv.setCacheColorHint(0); lv.setSelector(android.R.color.transparent); lv.setPadding(30, 0, 30, 0); lv.setVerticalScrollBarEnabled(false); lv.setBackgroundResource(R.drawable.list_background); lv.setDivider(new ColorDrawable(0x00000000)); setListAdapter(new MyArrayAdapter(this, classes)); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); String cheese = classes[position]; try { Intent ourIntent; if (position > 1 && position < 25) { Class ourClass = Class.forName("com.test.demo.MyDay"); ourIntent = new Intent(Menu.this, ourClass); ourIntent.putExtra("cheese", cheese); } else { Class ourClass = Class.forName("com.test.demo." + cheese); ourIntent = new Intent(Menu.this, ourClass); } startActivity(ourIntent); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public boolean onCreateOptionsMenu(android.view.Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.cool_menu, menu); getLayoutInflater().setFactory(new Factory() { public View onCreateView(String name, Context context, AttributeSet attrs) { if (name.equalsIgnoreCase( "com.android.internal.view.menu.IconMenuItemView")) { try { LayoutInflater li = LayoutInflater.from(context); final View view = li.createView(name, null, attrs); new Handler().post(new Runnable() { public void run() { view.setBackgroundResource(R.drawable.border3); ((TextView) view).setTextSize(25); ((TextView) view).setTypeface(FontFactory .getBFantezy(getBaseContext())); ((TextView) view).setTextColor(Color.RED); } }); return view; } catch (InflateException e) { } catch (ClassNotFoundException e) { } } return null; } }); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.aboutUs: Intent i = new Intent("com.test.demo.ABOUT"); startActivity(i); break; case R.id.preferences: Intent p = new Intent("com.test.demo.PREFS"); startActivity(p); break; case R.id.exit: finish(); break; } return false; } } 

MyArrayAdapter:

 public class MyArrayAdapter extends ArrayAdapter<String> { private final Activity context; private final String[] classes; Typeface tf; static class ViewHolder { public TextView text; public ImageView image; } public MyArrayAdapter(Activity context, String[] classes) { super(context, R.layout.row, classes); this.context = context; this.classes = classes; tf = Typeface.createFromAsset(context.getAssets(), "BFantezy.ttf"); } @Override public View getView(int position, View convertView, ViewGroup parent) { View rowView = convertView; if (rowView == null) { LayoutInflater inflater = context.getLayoutInflater(); rowView = inflater.inflate(R.layout.row, null); ViewHolder viewHolder = new ViewHolder(); viewHolder.text = (TextView) rowView.findViewById(R.id.row_label); viewHolder.image = (ImageView) rowView.findViewById(R.id.row_image); viewHolder.text.setTypeface(FontFactory.getBFantezy(getContext())); rowView.setTag(viewHolder); } ViewHolder holder = (ViewHolder) rowView.getTag(); String s = classes[position]; holder.text.setText(s); if (s.equals("Day one")) { holder.image.setImageResource(R.drawable.day1); } if (s.equals("Day Two")) { holder.image.setImageResource(R.drawable.day2); } if (s.equals("Day Three")) { holder.image.setImageResource(R.drawable.day3); } if (s.equals("Day Four")) { holder.image.setImageResource(R.drawable.day4); } if (s.equals("Day Five")) { holder.image.setImageResource(R.drawable.day5); } if (s.equals("Conclusion")) { holder.image.setImageResource(R.drawable.day_concl); } if (s.equals("DreamsTrip")) { holder.image.setImageResource(R.drawable.day_trip); } if (s.equals("Introduction")) { holder.image.setImageResource(R.drawable.day_intr); } return rowView; } } 

我的一天:

 public class MyDay extends Activity { final Context context = this; private Button button; TextView tv2, tv3, tv4; String day; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); Boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.day); if (customTitleSupported) { getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); } initializeTextViews(); } private void initializeTextViews() { tv2 = (TextView) findViewById(R.id.day_tv1); tv2.setTypeface(FontFactory.getBFantezy(getBaseContext())); tv3 = (TextView) findViewById(R.id.day_tv3); tv3.setTypeface(FontFactory.getDroidNaskh(getBaseContext())); day = getIntent().getStringExtra("cheese"); if (day.equalsIgnoreCase("Day One")) { tv2.setText(Html.fromHtml(getString(R.string.beginning))); tv3.setText(Html.fromHtml(getString(R.string.day1))); button = (Button) findViewById(R.id.city_button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // custom dialog final Dialog dialog = new Dialog(context, R.style.cust_dialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog); // set the custom dialog components - text, image and button TextView text = (TextView) dialog .findViewById(R.id.dialog_text); text.setTypeface(FontFactory.getBFantezy(getBaseContext())); text.setText(Html .fromHtml(getString(R.string.torusim_places_1))); Button dialogButton = (Button) dialog .findViewById(R.id.dialog_Button); dialogButton.setTypeface(FontFactory .getBFantezy(getBaseContext())); // if button is clicked, close the custom dialog dialogButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } else if (day.equalsIgnoreCase("Day Two")) { tv2.setText(Html.fromHtml(getString(R.string.beginning))); tv3.setText(Html.fromHtml(getString(R.string.day2))); button = (Button) findViewById(R.id.city_button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // custom dialog final Dialog dialog = new Dialog(context, R.style.cust_dialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog); // set the custom dialog components - text, image and button TextView text = (TextView) dialog .findViewById(R.id.dialog_text); text.setTypeface(FontFactory.getBFantezy(getBaseContext())); text.setText(Html .fromHtml(getString(R.string.torusim_places_2))); Button dialogButton = (Button) dialog .findViewById(R.id.dialog_Button); dialogButton.setTypeface(FontFactory .getBFantezy(getBaseContext())); // if button is clicked, close the custom dialog dialogButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } else if (day.equalsIgnoreCase("Day Three")) { tv2.setText(Html.fromHtml(getString(R.string.beginning))); tv3.setText(Html.fromHtml(getString(R.string.day3))); button = (Button) findViewById(R.id.city_button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // custom dialog final Dialog dialog = new Dialog(context, R.style.cust_dialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog); // set the custom dialog components - text, image and button TextView text = (TextView) dialog .findViewById(R.id.dialog_text); text.setTypeface(FontFactory.getBFantezy(getBaseContext())); text.setText(Html .fromHtml(getString(R.string.torusim_places_3))); Button dialogButton = (Button) dialog .findViewById(R.id.dialog_Button); dialogButton.setTypeface(FontFactory .getBFantezy(getBaseContext())); // if button is clicked, close the custom dialog dialogButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } else if (day.equalsIgnoreCase("Day Four")) { tv2.setText(Html.fromHtml(getString(R.string.beginning))); tv3.setText(Html.fromHtml(getString(R.string.day4))); button = (Button) findViewById(R.id.city_button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // custom dialog final Dialog dialog = new Dialog(context, R.style.cust_dialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog); // set the custom dialog components - text, image and button TextView text = (TextView) dialog .findViewById(R.id.dialog_text); text.setTypeface(FontFactory.getBFantezy(getBaseContext())); text.setText(Html .fromHtml(getString(R.string.torusim_places_4))); Button dialogButton = (Button) dialog .findViewById(R.id.dialog_Button); dialogButton.setTypeface(FontFactory .getBFantezy(getBaseContext())); // if button is clicked, close the custom dialog dialogButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } else if (day.equalsIgnoreCase("Day Five")) { tv2.setText(Html.fromHtml(getString(R.string.beginning))); tv3.setText(Html.fromHtml(getString(R.string.day5))); button = (Button) findViewById(R.id.city_button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // custom dialog final Dialog dialog = new Dialog(context, R.style.cust_dialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom_dialog); // set the // custom dialog components - text, image and button TextView text = (TextView) dialog .findViewById(R.id.dialog_text); text.setTypeface(FontFactory.getBFantezy(getBaseContext())); text.setText(Html .fromHtml(getString(R.string.torusim_places_5))); Button dialogButton = (Button) dialog .findViewById(R.id.dialog_Button); dialogButton.setTypeface(FontFactory .getBFantezy(getBaseContext())); // if button is clicked, close the custom dialog dialogButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } } public void handleClick(View v) { // Create an intent to start the new activity. Intent intent = new Intent(); intent.setClass(this, DayGallery.class); intent.putExtra("dayname", day); startActivity(intent); } } 

logcat的:

 D/AbsListView(14159): Get MotionRecognitionManager D/dalvikvm(14159): GC_FOR_ALLOC freed 81K, 9% free 12164K/13315K, paused 13ms, total 13ms I/dalvikvm-heap(14159): Grow heap (frag case) to 14.306MB for 1555216-byte allocation D/dalvikvm(14159): GC_CONCURRENT freed 2K, 8% free 13681K/14855K, paused 12ms+1ms, total 20ms D/dalvikvm(14159): GC_FOR_ALLOC freed 0K, 8% free 13681K/14855K, paused 10ms, total 10ms I/dalvikvm-heap(14159): Grow heap (frag case) to 16.941MB for 2764816-byte allocation D/dalvikvm(14159): GC_CONCURRENT freed 0K, 7% free 16381K/17607K, paused 12ms+2ms, total 23ms D/libEGL(14159): loaded /system/lib/egl/libEGL_mali.so D/libEGL(14159): loaded /system/lib/egl/libGLESv1_CM_mali.so D/libEGL(14159): loaded /system/lib/egl/libGLESv2_mali.so D/(14159): Device driver API match D/(14159): Device driver API version: 10 D/(14159): User space API version: 10 D/(14159): mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Tue Oct 16 15:37:13 KST 2012 D/OpenGLRenderer(14159): Enabling debug mode 0 D/dalvikvm(14159): GC_FOR_ALLOC freed 1732K, 16% free 15672K/18439K, paused 19ms, total 19ms E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length D/dalvikvm(14159): GC_CONCURRENT freed 691K, 13% free 16102K/18439K, paused 13ms+2ms, total 27ms E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length W/OpenGLRenderer(14159): Shape round rect too large to be rendered into a texture (680x12472, max=4096x4096) W/OpenGLRenderer(14159): Shape round rect too large to be rendered into a texture (688x12480, max=4096x4096) E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length E/SpannableStringBuilder(14159): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 

Solutions Collecting From Web of "果冻豆运行设备(SPAN_EXCLUSIVE_EXCLUSIVE跨度不能有一个零长度)的Listactivity错误"

为了理解这里发生的事情,这一切都始于一个关于TextView应该是什么和不应该是什么的devise决定。 根据Android的TextView源代码 :

 /** * Displays text to the user and optionally allows them to edit it. A TextView * is a complete text editor, however the basic class is configured to not * allow editing; see {@link EditText} for a subclass that configures the text * view for editing. 

这意味着,即使你所做的只是在屏幕上放置一段文字,隐藏在后面的是全文高亮,select和编辑设施。 这里发生的事情是,解决一个问题的一些小小的调整似乎干扰了其他一些function,并创build了一些日志行。 在这种情况下,通过Nexus 7错误“SPAN_EXCLUSIVE_EXCLUSIVE跨度不能有零长度”给予了更多的权重,其中似乎在某些android版本中,可以通过在文本(条目)字段中禁用自动完成function来解决此问题:

 View.setInputType( InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS ); 

这也可以在XML中使用相应的TextView标签来完成:

 android:inputType="none" 

有问题的线路似乎已经到达了Android 4.1(Jelly Bean), setSpan函数(例如2.2.3源码 vs 4.1.1源码 )。 日志行是由尝试在一个长度为零的string中设置跨度触发的。 这就是为什么设置它,以便不需要select文本的(子)部分应该避免这个错误,无论是由上述提示或通过使用:

 android:textIsSelectable="false" android:editable="false" 

一个更具推测性的解决scheme可能是确保在TextView永远不会有空白string,方法是将字符“\ u200b”(一个零宽度的非空字符)添加到TextView的每个string中,方法是重写setText (简单地将其添加到string的末尾)在自定义TextView或通过将其放在您的代码中发送到TextView的每个string。

对于那些喜欢钻研android系统并覆盖它的一部分的人来说,根据这个android源代码看起来好像有可能通过以下来解决这个问题。 但是,它绝对不能保证它的工作。 真正的勇敢(傻子)可以自己写一个完整的SpannableStringBuilder ….

  1. 创build陷阱条件的SpannableStringBuilder自己的forms。 这个例子只是静静地停下来,而不是像原文那样大声地停下来:

     import android.text.SpannableStringBuilder; public class MySpannableStringBuilder extends SpannableStringBuilder { // Taken from SpannableStringBuilder.java private static final int MARK = 1; private static final int POINT = 2; private static final int START_MASK = 0xF0; private static final int END_MASK = 0x0F; private static final int START_SHIFT = 4; MySpannableStringBuilder() { super(); } MySpannableStringBuilder(CharSequence text) { super(text); } MySpannableStringBuilder(CharSequence text, int start, int end) { super(text, start, end); } @Override public void setSpan(Object what, int start, int end, int flags) { // Determine if the error is going to be triggered, if so fail silently int flagsStart = (flags & START_MASK) >> START_SHIFT; int flagsEnd = flags & END_MASK; if (flagsStart == POINT && flagsEnd == MARK && start == end) { return; } // All good, so call the real routine super.setSpan(what, flagsStart, end, flagsEnd); } } 
  2. 创buildMyEditableFactory extends Editable.Factory并将其设置为返回您的SpannableStringBuilder:

     import android.text.Editable; public class MyEditableFactory extends Editable.Factory { private static MyEditableFactory sInstance = new MyEditableFactory(); /** * Returns this Editable Factory. */ public static Editable.Factory getInstance() { return sInstance; } public Editable newEditable(CharSequence source) { return new MySpannableStringBuilder(source); } } 

除了编写操作系统的自定义版本并将其放在手机上,我不确定还有什么可能的。

欢迎提出所有改进build议,以及在各种操作系统环境中使用此代码的反馈。

你使用哪个键盘的TextView? 对于一些键盘(这不是当地的Andorid),你可能会遇到这个问题。

参见: http : //support.swiftkey.net/forums/116693-2-bug-reports/suggestions/2994580-span-exclusive-exclusive-spans-cannot-have-a-zero-

编译器可能无法parsing/使用阿拉伯语(纠正我,如果我错了)文本。

您可以尝试通过明确设置UTF-8下的每个String

 String[] classes = { new String("example1".getBytes(), "UTF-8"), new String("example2".getBytes(), "UTF-8") }; 

onListItemClick equals调用执行相同的onListItemClick

 String cheese = new String(classes[position].getBytes(), "UTF-8"); if(cheese.equals(new String("المقدمة".getBytes(), "UTF-8"))) { cheese = new String("Introduction".getBytes(), "UTF-8"); } 

更好的是,制作一个方法。

 private Object stringUTF8(final Object string) { try { return new String(((String) string).getBytes(), "UTF-8"); } catch(UnsupportedEncodingException e) { e.printStackTrace(); return "error"; } }