我对此很陌生,所以我遵循了以下教程:Android: Consuming a Remote JSON API with Volley
我能够从我的API中获取数据,但我提取的资源有点复杂,而且我不知道如何处理它。
这是我得到的JSON:
{
"data":[
{
"id":"1",
"image":"http:\/\/lorempixel.com\/600\/600\/technics",
"user":{
"data":{
"id":"667636906616952",
"first_name":"Lowell",
"last_name":"Leuschke",
"email":"Esmeralda.Hessel@hotmail.com",
"joined":{
"date":"2015-10-09 15:03:19",
"timezone_type":3,
"timezone":"UTC"
}
}
},
"location":{
"data":{
"id":"249795421882013",
"name":"Wedding planner EV",
"type":"193705277324704",
"lat":"42.69649",
"lng":"23.32601"
}
},
"tags":{
"data":[
]
},
"likes":{
"data":[
]
}
}
]
}
这是Post
资源。我获取的方法与教程相同,这里是parse
方法:
private List<Post> parse(JSONObject json) throws JSONException {
ArrayList<Post> records = new ArrayList<>();
JSONArray jsonPosts = json.getJSONArray("data");
for (int i = 0; i < jsonPosts.length(); i++) {
JSONObject jsonPost = jsonPosts.getJSONObject(i);
String id = jsonPost.getString("id");
String image = jsonPost.getString("image");
Gson gson = new Gson();
final User user = gson.fromJson(jsonPost.getString("user"), User.class);
final Location location = gson.fromJson(jsonPost.getString("location"), Location.class);
Integer likes = jsonPost.getJSONObject("likes").getJSONArray("data").length();
Post record = new Post(id, image, user, location, likes);
records.add(record);
}
return records;
}
以下是我的课程。
User
:
public class User {
String id;
String firstName;
String lastName;
String email;
ApiDate joined;
public User(String id, String firstName, String lastName, String email, ApiDate joined) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.joined = joined;
}
public String getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public ApiDate getJoined() {
return joined;
}
public String getPictureUrl() {
return "https://graph.facebook.com/" + this.getId() + "/picture?type=normal";
}
}
Location
:
public class Location {
String id;
String name;
String type;
String lat;
String lng;
public Location(String id, String name, String type, String lat, String lng) {
this.id = id;
this.name = name;
this.type = type;
this.lat = lat;
this.lng = lng;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getLat() {
return lat;
}
public String getLng() {
return lng;
}
}
Post
:
import java.util.ArrayList;
public class Post {
String id;
String image;
User user;
Location location;
ArrayList<User> tags;
Integer likes;
public Post(String id, String image, User user, Location location, Integer likes) {
this.id = id;
this.image = image;
this.user = user;
this.location = location;
this.likes = likes;
}
public String getId() {
return id;
}
public String getImage() {
return image;
}
public User getUser() {
return user;
}
public Location getLocation() {
return location;
}
public Integer getLikes() {
return likes;
}
}
问题是,在此fetch
方法中,User
和Location
未正确设置。我相信存在错误,但我不知道如何处理这种情况。在此之后,我有PostsAdapter
之类的内容:
NetworkImageView profilePicture = (NetworkImageView) convertView.findViewById(R.id.profilePicture);
然后:
profilePicture.setImageUrl(post.getUser().getPictureUrl(), userPictureLoader);
但post.getUser().getPictureUrl()
似乎是空的。
根据要求:
JsonObjectRequest request = new JsonObjectRequest(
"http://my.rest.api/api/posts",
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
try {
List<Post> posts = parse(jsonObject);
mAdapter.swapPostRecords(posts);
} catch (JSONException e) {
Toast.makeText(getActivity(), "Unable to parse data: " + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("PH_DEBUG:", "Unable to parse data: " + e.getMessage());
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getActivity(), "Unable to fetch data: " + volleyError.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("PH_DEBUG:", "Unable to fetch data: " + volleyError.getMessage());
}
});
VolleyApplication.getInstance().getRequestQueue().add(request);
答案 0 :(得分:0)
有几种方法可以解决它,但我的建议是:
在API方面,当您对变量“image”进行编码时,如果您使用的是php,请尝试将url字符串编码为“urlencode”,以避免在编码JSON时使用“\ /”。
$url_encoded = urlencode($your_url_string);
使用“JSON_UNESCAPED_UNICODE”作为JSON编码的选项:
$my = json_encode($my_data,JSON_UNESCAPED_UNICODE);
结果你很可能在字段“image”中看到类似的内容:
"https%3A%2F%2Fendeavor.org.br%2profile_image.png"
在Android方面,当您收到JSON字符串时,请执行以下操作:
try {
myURL_Image_decoded = URLDecoder.decode(my_image_url, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.e("URL DECODE", myURL_Image_decoded);
这可以解决斜线编码“\ /".
的问题答案 1 :(得分:0)
如评论所述,因为在user
内部JSONObject是另一个data
JSONObject
因此,您应该使用
final User user = gson.fromJson(jsonPost.getJSONObject("user").getString("data"), User.class);
而不是
final User user = gson.fromJson(jsonPost.getString("user"), User.class);
适用于location
的相同逻辑。
P / S:为避免NPE,您还应检查JSON对象以确保它们不为空
希望这有帮助!