Facebook 在获取用户性别时出现 Android 错误

Facebook for Android error on getting gender of user

一些用户在我们的应用程序中注册 Facebook 时遇到强制关闭。我们在下面的行中收到了这个堆栈跟踪:

java.lang.StringIndexOutOfBoundsException: length=0; regionStart=0; regionLength=1
at java.lang.String.startEndAndLength(String.java:588)
at java.lang.String.substring(String.java:1475)
at com.yolify.android.Activity_Splash.onCompleted(Activity_Splash.java:483)
at com.facebook.Request.onCompleted(Request.java:281)
at com.facebook.Request.run(Request.java:1666)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
at dalvik.system.NativeStart.main(Native Method)

代码:

String gender = user.getProperty("gender") == null ?  "" :  user.getProperty("gender").toString();
String Gender = gender == null ? "" : gender.substring(0,1).toUpperCase(Locale.ENGLISH)+gender.substring(1);

强制关闭发生在代码的第二行。由于大约每 100 个注册中就有 1 个会发生这种情况,因此我们无法重现该问题。如果性别不为空那么它是什么?

"If the gender is not null then what is it?" :它可能是空的,但你把它变成了一个空字符串。然后 IndexOutOfBoundsException 来自尝试对该空字符串执行 substring(1)。

问题是你使用了两个背靠背的三元运算的方式。

第一个三元运算

String gender = user.getProperty("gender") == null ? "" : user.getProperty("gender").toString()

基本上是在说

if(user.getProperty("gender") == null){
    gender="";
}
else{
    gender=user.getProperty("gender").toString();
}

到目前为止一切顺利。 第二个三元运算(这就是让人困惑的地方。我不知道你为什么写'String Gender';我认为你应该换成'gender')

String Gender = gender == null ? "" : gender.substring(0,1).toUpperCase(Locale.ENGLISH)+gender.substring(1)

基本上是在说

if(gender == null){
    gender = ""; //gender instead of String Gender
}
else{
    gender = gender.substring(0,1).toUpperCase(Locale.ENGLISH) + substring(1)
}

请注意,由于第一个三元运算,第一个条件始终为假。基本上,如果有人使用性别为空的 facebook 帐户,第二个三元操作将始终抛出 IndexOutOfBoundsException,因为您的第一个三元操作生成一个空字符串,而您的第二个三元操作试图获取该空字符串的子字符串。一个简单的测试方法是创建一个新的 fb 帐户而不填写性别,然后登录您的应用程序。

修复:我倾向于避免像瘟疫这样的三元运算,因为即使它们节省了代码行,也很容易混淆,尤其是当你有两个背靠背处理相同的变量时。我会用

替换第二个三元运算
if(gender != "") { // Gender exists
    gender = gender.substring(0,1).toUpperCase(Locale.ENGLISH);
}
else{
    // gender us "" so do whatever
}

这就是我能想到的 "most correct way" 处理方式。您也可以尝试在第二个三元运算中去掉 +substring(1) ,这会消除错误,但这不是我推荐的。