java.lang.StringIndexOutOfBoundsException错误

时间:2013-11-26 16:25:28

标签: java android eclipse

我正在尝试进行本地验证。您在editText1中输入的每个组合(例如abc)都应转换为数字(a = 1,b = 2,c = 3)。 editText2中的文本应匹配转换为数字的abc(123)。如果是这样:启动新活动。 else:显示“登录失败”的textview。

 public class Login extends Activity {

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setTitle(R.string.login);
    setContentView(R.layout.home_login);
    Button btn = (Button) findViewById(R.id.loginButton2);

    EditText email_text = (EditText) findViewById(R.id.editText1);
    EditText code_text = (EditText) findViewById(R.id.editText2);
    final String userEmail = email_text.getText().toString(); 
    final String userCode = code_text.getText().toString(); 
    String x = "";

    for (int i = 0; i <= 2; i++) {
        x += getNumber(userEmail.charAt(i)); 
    }
    final int validCode = Integer.parseInt(x);

    btn.setOnClickListener(new OnClickListener() {

        @SuppressLint("ResourceAsColor")
        @Override
        public void onClick(View v) {
            if (userCode.equals(validCode)) {
                Intent intent = new Intent(Login.this, Home.class);
                startActivity(intent);
            } else {
                TextView view = (TextView) findViewById(R.id.loginfailed);
                view.setVisibility(View.VISIBLE);
                editText2.setText("");
            }
        }

    });

}

private int getNumber(Character c) {
    return "abdcefghijklmnopqrstuvwxyz".indexOf(c) + 1;
}

然而,当我运行我的应用程序时,它会立即崩溃并引发以下错误:

FATAL EXCEPTION:main 
java.lang.RuntimeException: Unable to start activity ComponentInfo {...}:
java.lang.StringIndexOutOfBoundsException: length=0; index=0

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:0)

您正在使用

 for (int i = 0; i <= 2; i++) {
        x += getNumber(userEmail.charAt(i)); 
 }

可能在输入任何数据之前。在public void onClick()内移动for循环,并始终检查userEmail是否为空。

示例

if(code_text.getText().toString().Length() > 1)
{
    for (int i = 0; i <= 2; i++) {
            x += getNumber(code_text.getText().toString().charAt(i)); 
     }
}

答案 1 :(得分:0)

当你初始化app时,email_text可能没有任何文本因此你得到一个长度为0的空字符串。我相信你可以通过转换为int并减去a来改进getnumber函数。固定号码。

return (int)c - fixedvalue;

有关字符的int值,请参阅http://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html

答案 2 :(得分:0)

更改

userEmail.addTextChangedListener(new TextWatcher() {

      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(userEmail.getText().length() > 0){
         for (int i = 0; i <= 2; i++) {
         x += getNumber(userEmail.charAt(i)); 
         }
         final int validCode = Integer.parseInt(x);
         }
      }

      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after) {

      }

      @Override
      public void afterTextChanged(Editable s) {

      }
    });

答案 3 :(得分:0)

您的代码中存在许多问题:

  • 首先,正如许多人所注意到的那样,当你的初始化时,你正在循环访问userEmail,因为你的编辑文本是空的;将其移至onClickListener;

  • 在onClickListener中
  • ,检查userEmail和userCode是否为空并且仅在此时继续,否则通知用户输入电子邮件和/或代码

  • 在你的else语句中,你不能直接使用id来访问editText2;因为你已经找到了ViewById,所以改变:

    editText2.setText("");
    

    code_text.setText("");
    
  • 在你的循环中,你已经硬编码了长度,这将适用于你的样本'abc'字符串,但是对于较长的字符串不会如预期的那样;将其更改为:

    for(int i=0; i<userEmail.length(); i++)  
    
  • 您正在构建x字符串,然后用它来创建validCode;这适用于最多10个字符的userEmail字符串 - 它将失败更长时间。为什么?您将validCode存储在整数变量中,最大int为2 ^ 31-1(2147483647),长度为10个字符。将validCode更改为long,甚至更好......

  • 而不是更改为长,为什么不比较字符串?而不是引入新变量,并将x字符串转换为数字,并且因为userCode已经是一个字符串,您可以简单地比较字符串,将String x =“”更改为:

    String validCode = "";
    
    if (userCode.equals(validCode)) {
        //rest of the code
    
  • 另外,在你的getNumber()方法中,你的return语句是:

    return "abdcefghijklmnopqrstuvwxyz".indexOf(c) + 1;
    

    “abdc ......”故意吗?不应该是“abcd ..”? :)

请参阅以下代码,并附上评论和修改:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle(R.string.login);
        setContentView(R.layout.home_login);
        Button btn = (Button) findViewById(R.id.loginButton2);

        final EditText email_text = (EditText) findViewById(R.id.editText1);
        final EditText code_text = (EditText) findViewById(R.id.editText2);

        btn.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("ResourceAsColor")
            @Override
            public void onClick(View v) {
                //check if user entered email and code, continue only if they have
                if (email_text.getText().length() > 0 && code_text.getText().length() > 0) {
                    //moved here, to avoid exception when text boxes are empty
                    final String userEmail = email_text.getText().toString();
                    final String userCode = code_text.getText().toString();

                    //changed from String x = "" because userCode is already a String
                    //and we don't have to change x to int, because we can compare 
                    //strings
                    String validCode = "";

                    //don't hardcode stop condition for i,
                    //instead, use the length of user entered string
                    for (int i = 0; i < userEmail.length(); i++) {
                        validCode += getNumber(userEmail.charAt(i));
                    }

                    //now we can compare userCode with validCode
                    if (userCode.equals(validCode)) {
                        Intent intent = new Intent(Login.this, Home.class);
                        startActivity(intent);
                    } else {
                        TextView view = (TextView) findViewById(R.id.loginfailed);
                        view.setVisibility(View.VISIBLE);

                        //reset string in code_text editText
                        code_text.setText("");
                    }
                }
                //userEmail or/and userCode text boxes are empty, inform user
                else {
                    Toast.makeText(getApplicationContext(), "Please enter email and/or code", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }