我有一个从数据库加载路由的Android应用程序。这些路由是LatLng对象的编码列表。我正在使用PolyUtil库来编码和解码LatLng对象列表:
final String encodedLatLngList = PolyUtil.encode(recordedLatLngList);
和
List<LatLng> decodedLatLngList = PolyUtil.decode(encodedLatLngList[i]);
通常一切都与这些列表和字符串的编码和解码完美配合,但是,从不同的设备上传的数据库中都有路由,这些路由都会投放:
routeID 55 caused java.lang.StringIndexOutOfBoundsException: length=879; index=879
routeID 65 caused java.lang.StringIndexOutOfBoundsException: length=171; index=171
routeID 66 caused java.lang.StringIndexOutOfBoundsException: length=215; index=215
数据库中保存的路径较长,没有出现问题的编码列表也没有空对象,因为在操作和插入之前,每个检索到的Location和LatLng对象都会针对null进行检查。有什么想法会导致这些问题吗?
这是本节的全部代码:
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, server_url, null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
// response
int count = 0;
int databaseEntries = response.length();
int[] routeID = new int[databaseEntries];
String[] encodedLatLngList = new String[databaseEntries];
int[] routeLength = new int[databaseEntries];
int[] routeColor = new int[databaseEntries];
String[] routeKeywords = new String[databaseEntries];
markerMap = new HashMap();
while (count < response.length()) {
try {
JSONObject jsonObject = response.getJSONObject(count);
routeID[count] = Integer.parseInt(jsonObject.getString("route_id")); //ID
encodedLatLngList[count] = jsonObject.getString("route_LatLngData");//Array
routeLength[count] = Integer.parseInt(jsonObject.getString("route_length")); //length
routeColor[count] = Integer.parseInt(jsonObject.getString("route_color")); //Color
routeKeywords[count] = jsonObject.getString("route_keywords");
count++;
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(context, "Something went wrong while trying to add existing routes to map", Toast.LENGTH_SHORT).show();
}
}
for (int i = 0; i < databaseEntries - 1; i++) {
try {
List<LatLng> decodedLatLngList = PolyUtil.decode(encodedLatLngList[i]);
// LatLng[] latLngArray = decodedLatLngList.toArray(new LatLng[0]);
// Route route = new Route(context, routeID[i], latLngArray, routeLength[i], routeColor[i], routeKeywords[i]);
} catch (Exception e) {
Log.d("filteredRoutes", "routeID: " + routeID[i] + " caused: " + e.toString());
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// error response
Toast.makeText(context, "Internet connection failed. loadAllAvailableRoutes file not found.", Toast.LENGTH_LONG).show();
}
}
);
//Adds post request to request queue using MySingleton class.
MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
}
堆栈跟踪如下所示:
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: java.lang.StringIndexOutOfBoundsException: length=80; index=80
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at java.lang.String.charAt(Native Method)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.google.maps.android.PolyUtil.decode(PolyUtil.java:464)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.universityofportsmouth.kaanapaydin.runarace.Route$1.onResponse(Route.java:157)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.universityofportsmouth.kaanapaydin.runarace.Route$1.onResponse(Route.java:115)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:83)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:106)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at android.os.Handler.handleCallback(Handler.java:743)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at android.os.Looper.loop(Looper.java:150)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5621)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at java.lang.reflect.Method.invoke(Native Method)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
04-22 02:55:14.403 2838-2838/com.universityofportsmouth.kaanapaydin.runarace D/filteredRoutes: routeID: 69 caused: java.lang.StringIndexOutOfBoundsException: length=80; index=80
使用失败行的PolyUtil解码方法:
public static List<LatLng> decode(String encodedPath) {
int len = encodedPath.length();
List<LatLng> path = new ArrayList();
int index = 0;
int lat = 0;
int lng = 0;
/*
* Modifying this line to len-1 caused proper functionality.
* Maybe one location is now missing on the other routes
* but that is still better than having no routes uloaded by other users.
*/
while(index < len) { //
int result = 1;
int shift = 0;
int b;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while(b >= 31);
lat += (result & 1) != 0?~(result >> 1):result >> 1;
result = 1;
shift = 0;
do {
b = encodedPath.charAt(index++) - 63 - 1; //this line enters a too high index
result += b << shift;
shift += 5;
} while(b >= 31);
lng += (result & 1) != 0?~(result >> 1):result >> 1;
path.add(new LatLng((double)lat * 1.0E-5D, (double)lng * 1.0E-5D));
}
return path;
}
导致索引异常的字符串:
tp|_Fy~ui`@??NHKR@RJPHJHP@HHPRDJEFAC@@?@??@@A@?B@?NBXDLJHHJLXBJDJDFFFFHNXNATEH??