Reputation: 16790
The following is my code. It works fine on the emulator. But when I run it on my android device, it crashes with java.lang.ClassCastException: java.lang.String at the line marked below. I can't find the place where the casting has gone wrong. Any help would be greatly appreciated! :)
public static MatrixCursor getRespAsCursor(String query) {
String url = (String)(API_URL + "?api_key=" + API_KEY + "&" + query);
System.out.println(url);
String resp = (String)getAPIResp(url);
JSONObject reply;
MatrixCursor emptyCursor = new MatrixCursor(new String[0]);
try {
reply = (JSONObject) new JSONTokener(resp).nextValue();//CRASHES HERE
String statusCode = (String)reply.getString("statusCode");
if(!statusCode.equals("200")) {
return emptyCursor;
}
int count = Integer.parseInt(reply.getString("count"));
if(count < 1) {
return emptyCursor;
}
JSONArray data = reply.getJSONArray("data");
//Get keys in String[] format
Iterator<String> keys = data.optJSONObject(0).keys();
List<String> copy = new ArrayList<String>();
//Add "_id" as adapters need it for traversal
copy.add("_id");
//copy rest of the keys
while (keys.hasNext())
copy.add(keys.next());
String[] sKeys = new String[copy.size()];
copy.toArray(sKeys);
int len = data.length();
//Create Cursor with JSON keys as columns
MatrixCursor resultCursor = new MatrixCursor(sKeys, len);
//Add rows to Cursor
for(int i = 0; i < len; i++) {
JSONObject d = data.optJSONObject(i);
List<Object> values = new ArrayList<Object>();
for(String key: copy) {
if(key.equals("_id")) {
values.add(Integer.toString(i));
}
else {
values.add(d.opt(key));
}
}
resultCursor.addRow(values);
}
return resultCursor;
}
catch(JSONException e) {
return emptyCursor;
}
}
Upvotes: 0
Views: 1540
Reputation: 1306
You might wanna have a look at JSONTokener javadoc
The doc says nextValue()
Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
You are probably getting the ClassCastException
as your line of code
reply = (JSONObject) new JSONTokener(resp).nextValue();//CRASHES HERE
does not return JSONObject.
You might want to check instance type of the returned object before typecasting it. For example,
Object obj = new JSONTokener(resp).nextValue();
if(obj instanceof JSONObject){
reply = (JSONObject)obj;
} else {
//Handle otherwise,
}
Upvotes: 2
Reputation: 1503629
You've already shown the place the casting goes wrong - it's here:
reply = (JSONObject) new JSONTokener(resp).nextValue();
nextValue()
is returning a String
, and you're casting it to JSONObject
.
I suspect the JSON isn't as you expect it to be - it's not a statusCode = "value"
pair; it's just the value.
You should check the JSON that you're returning, and either change to cast to a string, or if you want to be able to handle both forms of JSON, check the result with instanceof
before casting:
Object reply = new JSONTokener(resp).nextValue();
if (reply instanceof String) {
...
} else if (reply instanceof JSONObject) {
...
}
Upvotes: 5
Reputation: 157487
reply = (JSONObject) new JSONTokener(resp).nextValue();//CRASHES HERE
If you are getting a ClassCastException
is because the Object
returned by nextValue()
is not a JSONObject (probably a String
instance)
Upvotes: 1