Search code examples
javaandroidstringstring-concatenationnull-pointer

Resource ID showing instead of string when appending null message at the end


In one of my functions I produce a Toast message if there is an error. The message makes a call to a resource ID and fetches the message from the last error. If the last error returns null, then the actual int ID is shown, instead of the dereferenced string.

Toast.makeText(SelectionActivity.this, 
               (R.string.error_onCanceled + " " mLastError.getMessage()),  
                Toast.LENGTH_SHORT).show();

2131689536 null

Toast.makeText(SelectionActivity.this,
                (R.string.error_onCanceled),
                  Toast.LENGTH_SHORT).show();

On Canceled: error =
** this is my string from the resource file

I can't figure out why appending null to the end of the string makes it return the int ID instead of the string.


Solution

  • R.string.error_onCanceled is an int.

    There are two forms of makeText(). One takes an int, treating it as a string resource ID. The other takes a CharSequence or String.

    Toast.makeText(SelectionActivity.this,
                (R.string.error_onCanceled),
                  Toast.LENGTH_SHORT).show();
    

    This uses the one that takes an int and uses your string resource.

    For the other, you have R.string.error_onCanceled + " " mLastError.getMessage(). This does not compile. I am going to assume that you really mean R.string.error_onCanceled + " " + mLastError.getMessage(). In that case, all Java can do is:

    • Convert your int to a String

    • Concatenate it with the other strings

    But Java converts the int to a String literally, as Java has no idea about Android string resources.

    The most direct way to fix this is to use getString(R.string.error_onCanceled_) + " " + mLastError.getMessage(), so you ask Android to give you the string associated with the string resource ID.

    Or, you could change the string resource to have a %d in it:

    <string name="error_onCanceled">** this is my string from the resource file %s</string>
    

    Then, you would use getString(R.string.error_onCanceled, mLastError.getMessage()) to get the combined message to pass to the Toast.

    One way or another, if you are not passing the plain string resource ID into makeText(), you need to use getString().