So, Where Did We Go Wrong?

In both the Java and Kotlin editions of MainActivity and its updateButton() method, we have a simpler bit of code that tries to set the caption to just be the number of seconds that have elapsed:

  private fun updateButton() {
    val nowMs = SystemClock.elapsedRealtime()

    binding.showElapsed.setText(((nowMs - startTimeMs) / 1000).toInt())
  }
  void updateButton() {
    long nowMs = SystemClock.elapsedRealtime();
    int seconds = (int)((nowMs - startTimeMs) / 1000);

    binding.showElapsed.setText(seconds);
  }

This code compiles, because setText() on a Button has a variant that accepts an Int as a parameter. We are passing an Int that represents the number of seconds.

Let’s look at the relevant portion of the stack trace again:

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x11
    at android.content.res.Resources.getText(Resources.java:1334)
    at android.widget.TextView.setText(TextView.java:4917)
    at com.commonsware.jetpack.sampler.simpleboom.MainActivity.updateButton...

As it turns out, setText(Int) does not show that Int value as text in the Button caption. Instead, Android is expecting that to be a reference to a string resource, such as R.string.elapsed. Those R values are all integers, and so many functions in the Android SDK that accept an Int are expecting a resource ID, not some arbitrary value as we are providing. In particular, if you get crash with an android.content.res.Resources$NotFoundException, there is a good chance that you are passing in a value to a function that is not a valid resource ID.

The correct way to implement this would be to convert the numeric value to a String, then pass that to setText():

  private fun updateButton() {
    val nowMs = SystemClock.elapsedRealtime()

    binding.showElapsed?.setText(((nowMs - startTimeMs) / 1000).toString())
  }
  void updateButton() {
    long nowMs = SystemClock.elapsedRealtime();
    int seconds = (int)((nowMs - startTimeMs) / 1000);

    binding.showElapsed.setText(Integer.toString(seconds));
  }

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.