9

My app works greatly with the exception of a few devices. On one such device, I get a FATAL EXCEPTION in one of my activities. The error is java.lang.ClassCastException: java.lang.String cannot be cast to android.text.Spannable ... ... at android.widget.TextView.setEnabled(TextView.java:1432)

STACK TRACE

05-02 09:18:19.917: E/AndroidRuntime(20587): FATAL EXCEPTION: main
05-02 09:18:19.917: E/AndroidRuntime(20587): java.lang.ClassCastException: java.lang.String cannot be cast to android.text.Spannable
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.widget.TextView.setEnabled(TextView.java:1432)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at com.myapp.android.menu.LoginFragment.checkIfAnyFieldIsEmpty(LoginFragment.java:512)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at com.myapp.android.menu.LoginFragment.onCreateView(LoginFragment.java:183)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.os.Handler.handleCallback(Handler.java:615)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.os.Looper.loop(Looper.java:137)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at android.app.ActivityThread.main(ActivityThread.java:4962)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at java.lang.reflect.Method.invokeNative(Native Method)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at java.lang.reflect.Method.invoke(Method.java:511)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
05-02 09:18:19.917: E/AndroidRuntime(20587):    at dalvik.system.NativeStart.main(Native Method)

Here are the snippets of code surrounding the error.

XML LAYOUT CODE

<com.myapp.android.view.StyledButton
        android:id="@+id/login_sign_in"
        style="@style/button_blue"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/state_list_login"
        android:textColor="@color/white"
        android:imeOptions="actionDone"
        android:padding="10dp"
        android:text="@string/sign_in" />

CUSTOM BUTTON JAVA CODE

public class StyledButton extends Button {
//variables
private final String BOLD = "fonts/arial.ttf";
private final String NORMAL = "fonts/arial_bold.ttf";

private String mCustomFont = null;

/**
 * Constructor
 * @param context
 */
public StyledButton(Context context) {
    super(context);
}

/**
 * Constructor
 * @param context
 * @param attrs
 */
public StyledButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    setCustomAttributes(attrs);
}

/**
 * Set custom attributes
 * @param attrs
 */
private void setCustomAttributes(AttributeSet attrs) {
    TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.StyledTextView);
    mCustomFont = a.getString(R.styleable.StyledTextView_fontAsset);
    if(mCustomFont != null) {
        if(!isInEditMode()) {
            CustomFontManager fontManager = CustomFontManager.getInstance();
            super.setTypeface(fontManager.getFont(getContext().getAssets(), mCustomFont));
        }
    }
    a.recycle();
}

/**
 * Set type face
 */
public void setTypeface(Typeface tf, int style) {
    CustomFontManager fontManager = CustomFontManager.getInstance();
    if(isInEditMode()) {
        super.setTypeface(tf,style);
        return;
    }
    if(mCustomFont!=null) {
        super.setTypeface(fontManager.getFont(getContext().getAssets(), mCustomFont));
        return;
    }
    switch (style) {
        case Typeface.NORMAL:
            super.setTypeface(fontManager.getFont(getContext().getAssets(), NORMAL));
            break;
        case Typeface.BOLD:
            super.setTypeface(fontManager.getFont(getContext().getAssets(), BOLD));
            break;
        default:
            super.setTypeface(fontManager.getFont(getContext().getAssets(), NORMAL));
            break;
    }
}

}

JAVA CODE CAUSING ERROR

    private StyledButton mSignIn;

    public void checkIfAnyFieldIsEmpty() {
    if (mEmailEmpty || mPasswordEmpty) {
        mSignIn.setEnabled(false);
    } else {
        mSignIn.setEnabled(true);
    } 
}

The line of code mSignIn.setEnabled(false) is causing the error. If i comment it out or just replace it so both the if and else read mSignIn.setEnabled(true) the app runs fine.

Again. The code as is works fine on the majority of devices.

user1857437
  • 259
  • 3
  • 13
  • 1
    Please post the entire stack trace. – CommonsWare May 02 '13 at 14:29
  • i have added the stack trace – user1857437 May 02 '13 at 14:35
  • 1
    I cannot see in the source code for Android where `setEnabled()` references any `String` or `Spannable`. You are probably tripping over a bug in some manufacturer-specific modification to Android. You might wish to try to contact the manufacturer in question. – CommonsWare May 02 '13 at 14:38
  • thats what i'm thinking. i have multiple different devices from this manufacturer. the app runs smoothly on the majority of them but crashes on a few. will contacting them actually help? – user1857437 May 02 '13 at 14:40
  • You might take a look at `AnyTextView` (https://github.com/hanspeide/anytextview), which has a similar objective as your `StyledButton`, to see how it handles your typeface manipulations, and see if perhaps it survives better on these devices. "will contacting them actually help?" -- that would depend a bit on the manufacturer, which you have not yet disclosed. – CommonsWare May 02 '13 at 14:41
  • Samsung is the manufacturer – user1857437 May 02 '13 at 14:50
  • If you can create and post a sample project that reproduces the error, and indicate which devices it crashes on, I can try to get this some Samsung-ly attention. – CommonsWare May 02 '13 at 14:51
  • do you call setText(String) at some point on your button ? if this device's textview doesn't like String, you may consider creating and passing it a Spannable – njzk2 May 02 '13 at 14:52
  • no. i set the text in the xml layout. – user1857437 May 02 '13 at 15:37
  • i added this line to my xml layout "android:bufferType="spannable" and now no crash. happy i figured it out but i'm not sure as to why it was causing a crash especially when i have similiar buttons that dont cause a crash – user1857437 May 02 '13 at 17:25

3 Answers3

20

Did you make your style button as spannable? For example, TextView should be like this

TextView.setText("Hai", TextView.BufferType.SPANNABLE);

chain
  • 589
  • 9
  • 22
1

This may be a little bit late but, make sure the text in the TextView you are trying to Span isn't set as "". For some reason empty strings are not spannable.

N Droidev
  • 444
  • 4
  • 13
ono
  • 2,752
  • 9
  • 38
  • 78
-3

it seems like i was calling android:imeOptions="actionDone" in the xml layout file. i removed that and it didn't crash anymore.

why?

user1857437
  • 259
  • 3
  • 13