¿Qué es una excepción StringIndexOutOfBoundsException? ¿Cómo puedo arreglarlo?
Este es mi código:
private void bringData() {
final TextView mTextView = (TextView) findViewById(R.id.textView);
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://192.168.4.1:8080/";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
Es el valor predeterminado que se proporciona en la documentación de Android. Solo cambié la URL.
Este es mi mensaje de error:
java.lang.StringIndexOutOfBoundsException: longitud=28; regiónInicio=1; regionLength=499 en java.lang.String.substring(String.java:1931) en com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) en com.example.my.app.MainActivity$2. onResponse(MainActivity.java:46) en com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) en com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) en com.android .volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) en android.os.Handler.handleCallback(Handler.java:751) en android.os.Handler.dispatchMessage(Handler.java:95) en android.os. Looper.loop(Looper.java:154) en android.app.ActivityThread.main(ActivityThread.java:6077) en java.lang.reflect.Method.invoke(Método nativo) en com.android.internal.os.ZygoteInit$ MethodAndArgsCaller.run(ZygoteInit.java:865) en com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Durante la depuración, veo que mTextView.setText("Response is: "+ response.substring(0,500));
me entregan el mensaje, pero la vista de texto nunca se actualiza y la aplicación falla.
Específicamente, falla aquí dentro del archivo Looper.Java:
finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
etiqueta de seguimiento es 0.
Leí que algunos límites de cuerdas están mal pero no puedo encontrar cómo solucionarlo.
Error Message:
java.lang.StringIndexOutOfBoundsException: length=28; regionStart=1;
regionLength=499 at java.lang.String.substring(String.java:1931) at
com.example.my.app.MainActivity$2.onResponse(MainActivity.java:50) at
com.example.my.app.MainActivity$2.onResponse(MainActivity.java:46) at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) at
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) at android.os.Handler.handleCallback(Handler.java:751) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:154) at
android.app.ActivityThread.main(ActivityThread.java:6077) at
java.lang.reflect.Method.invoke(Native Method) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Error de descripción
There is an IndexOutOfBound exception occurred in your MainActivity class
Inside second inner class's OnResponse function as shown MainActivity$2onResponse
on line 46 which basically occurred during substring operation in String.java line 1931
which was invoked from StringRequest.deliverResponse at line 60,
which was invoked from StringRequest.deliverResponse at line 30,
which was invoked from ExecutorDelivery.java at line 99,
which intially started from ZygoteInit$MethodAndArgsCaller's run function
and reached up-to main thread of ActivityThread.main=>looper=>handler
Razón real
Su código intenta crear una subcadena con
starting index = 0
ending index = 500
aunque la longitud real de la cadena de respuesta es = 28, la longitud de la cadena no es lo suficientemente larga para crear una subcadena de 500 caracteres.
Soluciones:
Validar longitud usando operador ternario
?:
mTextView.setText("Response is: "+ ((response.length()>499) ? response.substring(0,500) : "length is too short"));
Nota: El operador ternario (
?:
) es una expresión corta,if else
pero no es una declaración, lo que significa que no puede ocurrir como una declaración atómicaINVALID
porque no hay asignación.((someString.length()>499) ? someString.substring(0,500):"Invalid length");
if-else
mejora la visibilidadString msg="Invalid Response"; if(response.length()>499){ msg=response.substring(0,500); } mTextView.setText("Response is: "+msg); //or mTextView.setText("Response is: "+response);
¿Qué es IndexOutOfBoundsException?
IndexOutOfBoundsException
es una subclase deRuntimeException
media, es una excepción no verificada que se lanza para indicar que un índice de algún tipo (como una matriz, una cadena o un vector) está fuera de rango. Por ejemplo, usando Lista.
como se muestra en la documentación
List<String> ls=new ArrayList<>();
ls.add("a");
ls.add("b");
ls.get(3); // will throw IndexOutOfBoundsException , list length is 2
Prevención :
String str = "";
int index =3;
if(index < ls.size()) // check, list size must be greater than index
str = ls.get(index);
else
// print invalid index or other stuff
Uso del constructor de clases con índice o mensaje de cadena
public IndexOutOfBoundsException() {
super();
}
public IndexOutOfBoundsException(String s) {
super(s);
}
¿Cuáles son otras variaciones/subclases de IndexOutOfBoundsException?
ArrayIndexOutOfBoundsException : esto indica que se ha accedido a una matriz con un índice ilegal. El índice es negativo o mayor o igual que el tamaño de la matriz, por ejemplo
int arr = {1,2,3} int error = arr[-1]; // no negative index allowed int error2 = arr[4]; // arr length is 3 as index range is 0-2
Prevención :
int num = "";
int index=4;
if(index < arr.length) // check, array length must be greater than index
num = arr[index];
else
// print invalid index or other stuff
StringIndexOutOfBoundsException : lo lanzan los métodos String para indicar que un índice es negativo o mayor que el tamaño de la cadena. Para algunos métodos como el método charAt, esta excepción también se produce cuando el índice es igual al tamaño de la cadena.
String str = "foobar"; // length = 6 char error = str.charAt(7); // index input should be less than or equal to length-1 char error = str.charAt(-1); // cannot use negative indexes
Prevención :
String name = "FooBar";
int index = 7;
char holder = '';
if(index < name.length()) // check, String length must be greater than index
holder = name.charAt(index) ;
else
// print invalid index or other stuff
Nota: length()
es una función de String
clase y length
es un campo asociativo de un array
.
¿Por qué ocurren estas excepciones?
- Uso de índice negativo con
arrays
ocharAt
funcionessubstring
- BeginIndex es menor
0
o endIndex es mayor que la longitud de la cadena de entrada para crearsubstring
o beginIndex es mayor que endIndex - Cuando
endIndex - beginIndex
el resultado es menor que0
- Cuando la cadena/matriz de entrada está vacía
INFORMACIÓN: Es trabajo de JVM crear el objeto de excepción apropiado y pasarlo al lugar donde ocurrió usando throw
la palabra clave como o también puede hacerlo manualmente usando throw
la palabra clave.
if (s == null) {
throw new IndexOutOfBoundsException("null");
}
Cómo puedo arreglar esto ?
- Analizando StackTrace
- Validar la cadena de entrada contra nulidad, longitud o índices válidos
- Uso de depuración o registros
- Usando el bloque de captura de excepción genérica
1.) Analizando StackTrace
Como se muestra al principio de esta publicación, stacktrace proporciona la información necesaria en los mensajes iniciales sobre dónde sucedió y por qué sucedió, de modo que usted pueda simplemente rastrear ese código y aplicar la solución requerida.
por ejemplo, el motivo StringIndexOutOfBoundsException
y luego busque el suyo, package name indicating your class file
luego vaya a esa línea y, teniendo en cuenta el motivo, simplemente aplique la solución
Es una ventaja si estudia la excepción y su causa también en la documentación.
2.) Validar la cadena de entrada contra nulidad, longitud o índices válidos
En caso de incertidumbre cuando no conoce la entrada real, como que la respuesta proviene del servidor (o tal vez sea un error o nada) o del usuario, siempre es mejor cubrir todos los casos inesperados, aunque créanme, a pocos usuarios siempre les gusta presionar. los límites de las pruebas , así que use input!=null && input.length()>0
o para índices, puede usar el operador ternario o if-else
las condiciones de verificación de límites
3.) Uso de depuración o registros
Puede probar el entorno de ejecución de su proyecto en modo de depuración agregando puntos de interrupción en su proyecto y el sistema se detendrá allí para esperar su siguiente acción y, mientras tanto, podrá examinar los valores de las variables y otros detalles.
Los registros son como puntos de control, por lo que cuando su control cruza este punto, generan detalles, básicamente son mensajes informativos proporcionados por el sistema o el usuario también puede colocar mensajes de registro usando mensajes Logs o Println.
4.) Uso del bloque de captura de excepción genérica
Try-catch
Siempre es útil manejar los bloques, RuntimeExceptions
por lo que puede usar varios catch
bloques para manejar sus posibles problemas y brindar los detalles apropiados.
try {
mTextView.setText("Response is: "+ response.substring(0,500));
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
System.out,println("Invalid indexes or empty string");
}
catch (NullPointerException e) { // mTextView or response can be null
e.printStackTrace();
System.out,println("Something went wrong ,missed initialization");
}
catch (Exception e) {
e.printStackTrace();
System.out,println("Something unexpected happened , move on or can see stacktrace ");
}
Referencias adicionales
¿Qué es una NullPointerException y cómo la soluciono?