使用 REST API 和 Android

Consuming REST API with Android

我对此很陌生,所以我遵循了以下教程: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 方法中 UserLocation 设置不正确。我相信这是错误的,但我不知道如何处理这种情况。在此之后我有一个 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);

有几种方法可以解决,但我的建议是:

在你 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);

这可能会解决斜杠编码“\ /”的问题。

如评论所述,因为 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 对象以确保它们不为 null

希望对您有所帮助!