API11(现在是12)和Spannable导致运行时NPE。

5

更新 5月14日

这是文本大小混合导致的问题,如果我替换

<item name  = "android:textSize">16sp</item> 

只需改变颜色,例如

<item name="android:textColor">#00ff00</item>

然后它可以正常运行。

logcat中的TextLine,measure的引用应该已经给了我提示。尽管如此,我仍想修复它,我相信其他人也需要在单个文本行中混合使用不同大小的文本。

更新于5月12日 - 本帖末尾显示了最小代码示例。

在SDK 2.0以上版本下运行良好的代码,在3.0模拟器中运行时会抛出空指针异常。我已经将其缩小到了我代码中唯一存在SpannableString的情况。我使用它来在屏幕顶部的横幅区域中放置一些不同字体大小的文本。logcat显示:

FATAL EXCEPTION: main
java.lang.NullPointerException
    at android.text.style.TextAppearanceSpan.updateDrawState(TextAppearanceSpan.java:209)
    at android.text.TextLine.handleRun(TextLine.java:848)
    at android.text.TextLine.measureRun(TextLine.java:399)
    at android.text.TextLine.measure(TextLine.java:278)
    at android.text.TextLine.metrics(TextLine.java:252)
    at android.text.Layout.measurePara(Layout.java:1432)
    at android.text.Layout.getDesiredWidth(Layout.java:89)
    at android.text.Layout.getDesiredWidth(Layout.java:68)
    at android.widget.TextView.onMeasure(TextView.java:5713)
    at android.view.View.measure(View.java:10577)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
    at android.view.View.measure(View.java:10577)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
    at android.view.View.measure(View.java:10577)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
    at android.view.View.measure(View.java:10577)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4270)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
    at android.view.View.measure(View.java:10577)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:764)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:519)
    at android.view.View.measure(View.java:10577)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4270)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:1876)
    at android.view.View.measure(View.java:10577)
    at android.view.ViewRoot.performTraversals(ViewRoot.java:885)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1944)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:126)
    at android.app.ActivityThread.main(ActivityThread.java:3997)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
    at dalvik.system.NativeStart.main(Native Method)

代码在定时器调用的处理程序中,它使用以下基本行向文本视图写入(省略了空值检查等)
TextView tvBanner = (TextView) findViewById(R.id.RefText);
.....
int startSpan = altDispStr.indexOf("\n");
int endSpan = altDispStr.length();
spanRange = new SpannableString(altDispStr);
spanRange.setSpan(new TextAppearanceSpan(this,
    R.style.custompoint), startSpan, endSpan,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

....
....
tvBanner.setText(spanRange);

当我在调试器中捕获它时(在拥有3GB RAM的3.0模拟器上并不容易),它可以顺利通过处理程序方法,spanRange不为null,但是空指针异常和FC会在主线程稍后发生。

TextView(RefTxt)位于一个名为infobar.xml的XML文件中,该文件被包含在main.xml中。 infobar的重要组件包括:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/BannerRelView"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#800000ff"
android:layout_width="wrap_content">
    <TextView
       android:id="@+id/BannerOptionsButton"      
       android:layout_alignParentRight="true"   
       ....     
     </TextView>
     <TextView
         android:id="@+id/BannerGPS"
         android:layout_toLeftOf="@+id/BannerOptionsButton"    
         ....
      </TextView>
      <TextView
         android:id="@+id/RefText"
         android:layout_toLeftOf="@+id/BannerGPS"
         ......
      </TextView>
</RelativeLayout>

如果我将SpannableString替换为普通的String,则应用程序在3.0模拟器中运行。 我想知道是否需要采取任何额外措施来处理Spannables和平板设备?
当它死亡时,调试透视图显示 crash state - mt和tl都不为空
更新示例 我已将其缩减为最小代码示例,可演示该错误,在2.1下可以正常工作,但在3.0下会崩溃。
活动代码:
public class SpanTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String dispStr = "I'm the first line\nI'm the second line";
        TextView tvBanner = (TextView) findViewById(R.id.textView1);
        int startSpan = dispStr.indexOf("\n");
        int endSpan = dispStr.length();
        Spannable spanRange = new SpannableString(dispStr);
        spanRange.setSpan(new TextAppearanceSpan(this, R.style.custompoint), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        tvBanner.setText(spanRange);
    }
}

main.xml是一个包含一个TextView的LinearLayout。我的styles.xml文件中包含自定义点(custompoint):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style
        name="custompoint">
        <item name="android:textSize">24sp</item>
        <item name="android:textStyle">bold</item>
    </style>
</resources>

.

1个回答

7

您的TextView正在使用一个没有设置linkColor的TextPaint对象。我看到您正在使用的样式/主题某种方式上没有设置linkColor。尝试向样式中添加linkColor,看看是否解决了您的问题。

编辑:您可能应该继承默认样式,这将给您想要的结果。不确定为什么行为从2.1变为3.0,但是...


它最终接受了<item name="android:textColorLink">#0000ff</item>,然后我在代码中加入了TextAppearanceSpan tas = new TextAppearanceSpan(ctx, R.style.custompoint); ColorStateList csl = tas.getLinkTextColor();。它成功识别了,但仍然像以前一样崩溃了。(我希望Google能在他们的命名约定中保持一些一致性!) - NickT
尝试使用<item name="textColorLink">#ff0000</item> - Femi
3
我稍微分解了代码并添加了TextAppearanceSpan tas = new TextAppearanceSpan(this, R.style.custompoint); MetricAffectingSpan mas = tas.getUnderlying(); 调试器显示mas.mTypeface为空。将样式中的字体设置为sans,它在调试器中显示并正常运行。将其设置为normal,它再次显示为空但正常运行!?不明白!似乎样式需要添加textColor和typeface两个属性才能在API11下运行。所以感谢您指出了一半的解决方案(+1) - NickT
很高兴听到它起作用了:通常不从父主题继承是可以的,但据我所知,3.0 对此更加严格。 - Femi
4
parent="@android:style/TextAppearance" 对我有用,感谢你引导我朝这个方向。可惜这只是一个3.2的bug。 - Chris.Jenkins
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接