什么是IndexOutOfBoundsException?我该如何解决?

时间:2016-10-12 18:56:28

标签: java android android-volley

这是我的代码:

    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);
}

它是android文档中给出的默认值。我只更改了网址。

这是我的错误消息:

  

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)                         在com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)                         在com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)                         在com.android.volley.ExecutorDelivery $ ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)                         在android.os.Handler.handleCallback(Handler.java:751)                         在android.os.Handler.dispatchMessage(Handler.java:95)                         在android.os.Looper.loop(Looper.java:154)                         在android.app.ActivityThread.main(ActivityThread.java:6077)                         at java.lang.reflect.Method.invoke(Native Method)                         在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:865)                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

在调试期间,我看到mTextView.setText("Response is: "+ response.substring(0,500));我的消息已发送给我,但文本视图从未更新,应用程序崩溃。

具体来说,它在Looper.Java文件中崩溃:

finally {
if (traceTag != 0) {
   Trace.traceEnd(traceTag);
} 

traceTag为0。

我读到一些字符串边界是错误的,但我找不到如何解决它。

1 个答案:

答案 0 :(得分:11)

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) 

错误说明

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

实际原因

您的代码尝试使用

创建子字符串
starting index = 0
ending index = 500

虽然你的实际响应字符串长度是= 28,所以字符串长度不足以创建500个字符的子字符串。

解决方案:

  1. 使用三元运算符?:

    验证长度
    mTextView.setText("Response is: "+ 
       ((response.length()>499) ? response.substring(0,500) : "length is too short"));
    

    注意:三元运算符(?:)是if else的简短表达式,但它是not a statement意味着它不能作为原子语句出现,因为它是 {{1} } 因为没有作业

    INVALID
  2. ((someString.length()>499) ? someString.substring(0,500):"Invalid length"); 增强了可见性

    if-else
  3. 什么是IndexOutOfBoundsException?

      

    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意思的子类   它是一个未经检查的异常,它被抛出以指示索引   某种形式(例如数组,字符串或向量)已经出局   range.e.g使用List。

    Documentation

    所示
    RuntimeException

    预防

    List<String> ls=new ArrayList<>();
          ls.add("a");
          ls.add("b");
          ls.get(3); // will throw IndexOutOfBoundsException , list length is 2
    

    使用索引或字符串消息的类构造函数用法

    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
    

    IndexOutOfBoundsException的其他变体/子类是什么?

    • ArrayIndexOutOfBoundsException:这表示已使用非法索引访问了数组。索引是负数或大于或等于数组的大小,例如

      public IndexOutOfBoundsException() {
          super();
      }
      
      public IndexOutOfBoundsException(String s) {
          super(s);
      }
      

    预防

    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
    
    • StringIndexOutOfBoundsException:这是String方法抛出的,表示索引是负数或大于字符串的大小。对于某些方法(如charAt方法),当索引等于字符串的大小时,也会抛出此异常。

      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
      

    预防

    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
    

    注意: 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 length()类的函数,Stringlength的关联字段。

    为什么会发生这些异常?

    • 使用arrayarrayscharAt函数的负数索引
    • BeginIndex小于substring或endIndex大于创建0或beginIndex大于endIndex的输入字符串的长度
    • substring结果小于endIndex - beginIndex
    • 输入字符串/数组为空时

    信息:JVM的工作是创建适当异常的对象并将其传递到使用0关键字的地方,或者也可以手动执行也使用throw关键字。

    throw

    我该如何解决这个问题?

    1. 分析StackTrace
    2. 根据无效,长度或有效索引验证输入字符串
    3. 使用调试或日志
    4. 使用Generic Exception catch块
    5. 1.)分析StackTrace

      如本文开头所示,stacktrace在初始消息中提供了有关其发生位置的必要信息,为什么会发生这种情况,因此您只需跟踪该代码并应用所需的解决方案。

      例如原因if (s == null) { throw new IndexOutOfBoundsException("null"); } 然后查找您的StringIndexOutOfBoundsException然后转到该行并记住原因,只需应用解决方案

      如果您在文档中研究异常及其原因,那么这是一个良好的开端。

      2.。)针对nullity,length或valid索引验证输入字符串

      如果您不知道实际输入(例如响应来自服务器(或者可能是错误或没有)或用户),如果不确定,那么最好覆盖所有意外情况虽然相信我很少有用户总是喜欢突破测试的极限所以使用package name indicating your class file或索引,你可以使用三元运算符或input!=null && input.length()>0边界检查条件

      3.。使用调试或日志

      您可以通过在项目中添加断点来在调试模式下测试项目的运行环境,系统将停在那里等待您的下一个操作,同时您可以查看变量的值和其他详细信息。

      日志就像检查点一样,所以当你的控制跨越这一点时,他们会生成详细信息,基本上它们是由枯萎系统提供的信息性消息,或者用户也可以使用Logs或Println消息发送日志消息

      4.使用Generic Exception catch块

      if-else块对于处理Try-catch总是有用的,因此您可以使用多个RuntimeExceptions块来处理可能出现的问题并提供相应的详细信息

      catch

      进一步参考

      What is a NullPointerException, and how do I fix it?