2011-05-11 9 views
5

actualización decima cuarta de mayo deAPI11 (y now12) y Spannable causando tiempo de ejecución NPE

Es la mezcla de tamaños de texto que se rompe, si se sustituye la

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

con sólo un cambio de color como

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

entonces funciona bien.

Las referencias a TextLine, medida en el logcat deberían haberme dado una pista. Aunque me gustaría arreglarlo, estoy seguro de que otros necesitarán una combinación de tamaños en una sola línea de texto.

Udpdated 12 de mayo de - un mínimo ejemplo de código se muestra al final de este post

Código, que funciona bien bajo SDK 2.everything, lanza una excepción de puntero nulo cuando se ejecuta en un emulador de 3.0. Lo reduje a la única incidencia de SpannableString en mi código. Estoy usando esto para poner texto de diferentes tamaños de fuente en un área de pancarta en la parte superior de la pantalla. El Logcat es:

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) 

El código está en un controlador denominado por un temporizador, escribe en una vista de texto con las siguientes líneas esenciales (cheques nulos etc omitido)

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); 

Cuando la trampa se en el depurador (no es fácil con el emulador de 3.0 y 3 GB de RAM) se consigue a través del método de control OK, - spanRange no es nulo, pero el NPE y FC suceden más adelante en el looper principal.

La vista de texto (RefTxto) está en un xml llamado infobar.xml que se incluye en main.xml. componentes esenciales de la barra de información son:

<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> 

Si se sustituye la SpannableString con una cadena simple y llano a continuación, las carreras de aplicaciones en 3.0 emuladores. Me pregunto si hay alguna medida adicional que deba tomar con Spannables y tabletas.

Cuando muere, la perspectiva de depuración muestra crash state - TM y TL son ambos no nula

ejemplo de actualización de He reducido esto al ejemplo de código más pequeño que demuestra el error, que está bien bajo 2.1, pero se estrella con el mismo NPE con el código 3.0

Actividad:

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 es un LinearLayout que contiene solo el TextView. Mi styles.xml que contiene custompoint es:

<?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> 

.

Respuesta

7

Su TextView está utilizando un objeto TextPaint que no tiene el conjunto linkColor. Veo que el estilo/tema que estás utilizando no está configurando el linkColor de alguna manera.Intente agregar un linkColor al estilo y vea si eso resuelve su problema.

EDITAR: probablemente debería heredar el estilo predeterminado, y eso le dará lo que quiere. No estoy seguro de por qué el comportamiento cambió de 2.1 a 3.0, pero ...

+0

¿Cómo configuro el linkColor? Agregar # ff0000 da un error y un Google en linkColor no me da una pista – NickT

+0

Finalmente aceptó # 0000ff y luego puse TextAppearanceSpan tas = new TextAppearanceSpan (ctx, R.style.custompoint); \t \t ColorStateList csl = tas.getLinkTextColor(); en el código. Lo recogió bien, pero igual murió como antes. (¡Ojalá Google pusiera cierta coherencia en sus convenciones de nombres!) – NickT

+0

Pruebe ' # ff0000'. – Femi

Cuestiones relacionadas