This is my code:
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);
}
It's the default given from the android documentation. I only changed the url.
This is my 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)
During debugging I see that at mTextView.setText("Response is: "+ response.substring(0,500));
my message is delivered to me but the textview is never updated and the app crashes.
Specifically, it crashes here inside the Looper.Java file:
finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
traceTag is 0.
I read that some string bounds are wrong but I cannot find out how to fix it.
java.lang.StringIndexOutOfBoundsException. Thrown by String methods to indicate that an index is either negative or greater than the size of the string. For some methods such as the charAt method, this exception also is thrown when the index is equal to the size of the string.
The “TypeError: string index out of range” error is raised when you try to access an item at an index position that does not exist. You solve this error by making sure that your code treats strings as if they are indexed from the position 0.
The string index out of range means that the index you are trying to access does not exist. In a string, that means you're trying to get a character from the string at a given point. If that given point does not exist , then you will be trying to get a character that is not inside of the string.
The ArrayIndexOutOfBoundsException is a Runtime Exception thrown only at runtime. The Java Compiler does not check for this error during the compilation of a program.
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 Description
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
Actual Reason
Your code trying to create a substring with
starting index = 0
ending index = 500
though your actual response string length is = 28, so String length is not long enough to create a substring of 500 characters.
Solutions :
Validate length using ternary operator ?:
mTextView.setText("Response is: "+
((response.length()>499) ? response.substring(0,500) : "length is too short"));
Note : Ternary operator (?:
) is a short expression of if else
but it is not a statement mean it cannot occur as an atomic statement as this is INVALID
because there is no assignment
((someString.length()>499) ? someString.substring(0,500):"Invalid length");
if-else
enhances the visibility
String msg="Invalid Response";
if(response.length()>499){
msg=response.substring(0,500);
}
mTextView.setText("Response is: "+msg);
//or mTextView.setText("Response is: "+response);
IndexOutOfBoundsException
is a subclass ofRuntimeException
mean it is an unchecked exception which is thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.e.g using List.
as shown in the Documentation
List<String> ls=new ArrayList<>(); ls.add("a"); ls.add("b"); ls.get(3); // will throw IndexOutOfBoundsException , list length is 2
Prevention :
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
public IndexOutOfBoundsException() {
super();
}
public IndexOutOfBoundsException(String s) {
super(s);
}
ArrayIndexOutOfBoundsException : This indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array for e.g
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
Prevention :
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 : This is thrown by String methods to indicate that an index is either negative or greater than the size of the string. For some methods such as the charAt method, this exception also is thrown when the index is equal to the size of the string.
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
Prevention :
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
Note: length()
is a function of String
class and length
is a associative field of an array
.
arrays
or charAt
, substring
functions0
or endIndex is greater than the length of input string to create substring
or beginIndex is larger than the endIndexendIndex - beginIndex
result is less than 0
INFO : It is job of JVM to create the object of appropriate exception and pass it to the place of , where it occurred using throw
keyword like or you can also do it manually using throw
keyword too.
if (s == null) {
throw new IndexOutOfBoundsException("null");
}
As shown at the beginning of this post , stacktrace provides the necessary information in the initial messages about where it happen , why it happen so you can simply trace that code and apply the required solution .
for e.g the reason StringIndexOutOfBoundsException
and then look for your package name indicating your class file
then go to that line and keeping the reason in mind , simply apply the solution
It's a head start if you study about the exception and its cause as well in documentation.
In case of uncertainty when you don't know about the actual input like response is coming from server (or maybe it's an error or nothing) or user then it's always better to cover all the unexpected cases though believe me few users always like to push the limits of testing so use input!=null && input.length()>0
or for indexes, you can use the ternary operator or if-else
boundary check conditions
You can test the running environment of your project in debug mode by adding break-points in your project and system will stop there to wait for your next action and meanwhile you can look into the values of variables and other details.
Logs are just like check-points so when your control cross this point they generate details , basically they are informative messages given by wither system or user can also put logging messages using either Logs or Println messages
Try-catch
blocks are always useful to handle RuntimeExceptions
so you can use multiple catch
block along to handle your possible issues and to give appropriate details
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 ");
}
Further References
What is a NullPointerException, and how do I fix it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With