使用Unsplash API使用关键字的Searchview

时间:2019-02-21 13:27:40

标签: android api retrofit2 paging android-livedata

我正在调用我的应用 Unsplash API 。我想根据关键字获取照片。

但是我不能在我的模型 URL 中出现问题,并且出现此错误:

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

我正在将分页库 LiveData 一起使用,但是我不知道如何正确地做到这一点。

这是我的PhotoDataSource:

  override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Photo>) {
    networkState.postValue(NetworkState.LOADING)
    initialLoad.postValue(NetworkState.LOADING)

    photoService.search("nature", FIRST_PAGE_NUMBER, params.requestedLoadSize).enqueue(object : Callback<List<Photo>>{
        override fun onFailure(call: Call<List<Photo>>, t: Throwable) {
            // keep a Completable for future retry
            setRetry(Action { loadInitial(params, callback) })
            val error = NetworkState.error(t.message)
            // publish the error
            networkState.postValue(error)
            initialLoad.postValue(error)
        }

        override fun onResponse(call: Call<List<Photo>>, response: Response<List<Photo>>) {
            if (response.body() != null) {
                setRetry(null)
                val data = response.body()
                val items = data?.map { it } ?: emptyList()
                networkState.postValue(NetworkState.LOADED)
                initialLoad.postValue(NetworkState.LOADED)
                callback.onResult(items, null, FIRST_PAGE_NUMBER + INCREMENT_PAGE_VALUE)
            }
        }
    })
}

override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Photo>) {
    networkState.postValue(NetworkState.LOADING)

    Timber.d("Fetching next page: ${params.key}")
    photoService.search("nature", params.key, params.requestedLoadSize).enqueue(object : Callback<List<Photo>> {
        override fun onFailure(call: Call<List<Photo>>, t: Throwable) {
            // keep a Completable for future retry
            setRetry(Action { loadAfter(params, callback) })
            // publish the error
            networkState.postValue(NetworkState.error(t.message))
        }

        override fun onResponse(call: Call<List<Photo>>, response: Response<List<Photo>>) {
            if (response.body() != null) {
                val data = response.body()
                val items = data?.map { it } ?: emptyList()
                setRetry(null)
                networkState.postValue(NetworkState.LOADED)
                callback.onResult(items, params.key + INCREMENT_PAGE_VALUE)
            }
        }

    })
}

在这里,我有照片对象:

   @Parcelize
data class Photo (val urls: @RawValue Urls? = null,
                  val color: String? = null,
                  val width: Int? = null,
                  val height: Int? = null,
                  val created_at: String? = null,
                  val id: String? = null,
                  val user: @RawValue User? = null,
                  val links: @RawValue Links? = null,
                  val likes: Int? = null,
                  val downloads: Int? = null,
                  val description: String? = null,
                  val location: @RawValue Location? = null,
                  val exif: @RawValue Exif? = null
):Parcelable

在这里,我叫API PhotoService:

  @GET("search/photos")
fun search(@Query("query") query: String, @Query("per_page") perPage: Int, @Query("page") page: Int): Call<List<Photo>>

以下是JSON Response:

中的完整代码
   {
      "total": 133,
      "total_pages": 7,
      "results": [
        {
          "id": "eOLpJytrbsQ",
          "created_at": "2014-11-18T14:35:36-05:00",
          "width": 4000,
          "height": 3000,
          "color": "#A7A2A1",
          "likes": 286,
          "liked_by_user": false,
          "description": "A man drinking a coffee.",
          "user": {
            "id": "Ul0QVz12Goo",
            "username": "ugmonk",
            "name": "Jeff Sheldon",
            "first_name": "Jeff",
            "last_name": "Sheldon",
            "instagram_username": "instantgrammer",
            "twitter_username": "ugmonk",
            "portfolio_url": "http://ugmonk.com/",
            "profile_image": {
              "small": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32&s=7cfe3b93750cb0c93e2f7caec08b5a41",
              "medium": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64&s=5a9dc749c43ce5bd60870b129a40902f",
              "large": "https://images.unsplash.com/profile-1441298803695-accd94000cac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128&s=32085a077889586df88bfbe406692202"
            },
            "links": {
              "self": "https://api.unsplash.com/users/ugmonk",
              "html": "http://unsplash.com/@ugmonk",
              "photos": "https://api.unsplash.com/users/ugmonk/photos",
              "likes": "https://api.unsplash.com/users/ugmonk/likes"
            }
          },
          "current_user_collections": [],
          "urls": {
            "raw": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f",
            "full": "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f",
            "regular": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&s=92f3e02f63678acc8416d044e189f515",
            "small": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&s=263af33585f9d32af39d165b000845eb",
            "thumb": "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=8aae34cf35df31a592f0bef16e6342ef"
          },
          "links": {
            "self": "https://api.unsplash.com/photos/eOLpJytrbsQ",
            "html": "http://unsplash.com/photos/eOLpJytrbsQ",
            "download": "http://unsplash.com/photos/eOLpJytrbsQ/download"
          }
        },
        // more photos ...
      ]
    }

我不知道该怎么办,我在互联网上看到了很多教程,但我无能为力。我希望你能帮助我。

2 个答案:

答案 0 :(得分:2)

  

期望BEGIN_ARRAY,但在第1行第2列路径$ BEGIN_OBJECT中

此错误表明您的响应中有一个关键字具有对象,但是您将其作为数组对象进行访问。

  

解决方案:-

检查作为对象提及的关键字。

尝试在响应对象中作为对象

 @GET("search/photos")
fun search(@Query("query") query: String, @Query("per_page") perPage: Int, @Query("page") page: Int): Call<Example>

编辑:-

在您的项目中使用这些类,并使用示例进行改造。

  

Example.class

public class Example {

@SerializedName("total")
@Expose
private Integer total;
@SerializedName("total_pages")
@Expose
private Integer totalPages;
@SerializedName("results")
@Expose
private List<Result> results = null;

public Integer getTotal() {
return total;
}

public void setTotal(Integer total) {
this.total = total;
}

public Integer getTotalPages() {
return totalPages;
}

public void setTotalPages(Integer totalPages) {
this.totalPages = totalPages;
}

public List<Result> getResults() {
return results;
}

public void setResults(List<Result> results) {
this.results = results;
}

}
  

Links.class

public class Links {

@SerializedName("self")
@Expose
private String self;
@SerializedName("html")
@Expose
private String html;
@SerializedName("photos")
@Expose
private String photos;
@SerializedName("likes")
@Expose
private String likes;

public String getSelf() {
return self;
}

public void setSelf(String self) {
this.self = self;
}

public String getHtml() {
return html;
}

public void setHtml(String html) {
this.html = html;
}

public String getPhotos() {
return photos;
}

public void setPhotos(String photos) {
this.photos = photos;
}

public String getLikes() {
return likes;
}

public void setLikes(String likes) {
this.likes = likes;
}

}
  

Links_.class

public class Links_ {

@SerializedName("self")
@Expose
private String self;
@SerializedName("html")
@Expose
private String html;
@SerializedName("download")
@Expose
private String download;

public String getSelf() {
return self;
}

public void setSelf(String self) {
this.self = self;
}

public String getHtml() {
return html;
}

public void setHtml(String html) {
this.html = html;
}

public String getDownload() {
return download;
}

public void setDownload(String download) {
this.download = download;
}

}
  

ProfileImage.class

public class ProfileImage {

@SerializedName("small")
@Expose
private String small;
@SerializedName("medium")
@Expose
private String medium;
@SerializedName("large")
@Expose
private String large;

public String getSmall() {
return small;
}

public void setSmall(String small) {
this.small = small;
}

public String getMedium() {
return medium;
}

public void setMedium(String medium) {
this.medium = medium;
}

public String getLarge() {
return large;
}

public void setLarge(String large) {
this.large = large;
}

}
  

Result.class

public class Result {

@SerializedName("id")
@Expose
private String id;
@SerializedName("created_at")
@Expose
private String createdAt;
@SerializedName("width")
@Expose
private Integer width;
@SerializedName("height")
@Expose
private Integer height;
@SerializedName("color")
@Expose
private String color;
@SerializedName("likes")
@Expose
private Integer likes;
@SerializedName("liked_by_user")
@Expose
private Boolean likedByUser;
@SerializedName("description")
@Expose
private String description;
@SerializedName("user")
@Expose
private User user;
@SerializedName("current_user_collections")
@Expose
private List<Object> currentUserCollections = null;
@SerializedName("urls")
@Expose
private Urls urls;
@SerializedName("links")
@Expose
private Links_ links;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getCreatedAt() {
return createdAt;
}

public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}

public Integer getWidth() {
return width;
}

public void setWidth(Integer width) {
this.width = width;
}

public Integer getHeight() {
return height;
}

public void setHeight(Integer height) {
this.height = height;
}

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

public Integer getLikes() {
return likes;
}

public void setLikes(Integer likes) {
this.likes = likes;
}

public Boolean getLikedByUser() {
return likedByUser;
}

public void setLikedByUser(Boolean likedByUser) {
this.likedByUser = likedByUser;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public List<Object> getCurrentUserCollections() {
return currentUserCollections;
}

public void setCurrentUserCollections(List<Object> currentUserCollections) {
this.currentUserCollections = currentUserCollections;
}

public Urls getUrls() {
return urls;
}

public void setUrls(Urls urls) {
this.urls = urls;
}

public Links_ getLinks() {
return links;
}

public void setLinks(Links_ links) {
this.links = links;
}

}
  

Urls.class

public class Urls {

@SerializedName("raw")
@Expose
private String raw;
@SerializedName("full")
@Expose
private String full;
@SerializedName("regular")
@Expose
private String regular;
@SerializedName("small")
@Expose
private String small;
@SerializedName("thumb")
@Expose
private String thumb;

public String getRaw() {
return raw;
}

public void setRaw(String raw) {
this.raw = raw;
}

public String getFull() {
return full;
}

public void setFull(String full) {
this.full = full;
}

public String getRegular() {
return regular;
}

public void setRegular(String regular) {
this.regular = regular;
}

public String getSmall() {
return small;
}

public void setSmall(String small) {
this.small = small;
}

public String getThumb() {
return thumb;
}

public void setThumb(String thumb) {
this.thumb = thumb;
}

}
  

User.class

public class User {

@SerializedName("id")
@Expose
private String id;
@SerializedName("username")
@Expose
private String username;
@SerializedName("name")
@Expose
private String name;
@SerializedName("first_name")
@Expose
private String firstName;
@SerializedName("last_name")
@Expose
private String lastName;
@SerializedName("instagram_username")
@Expose
private String instagramUsername;
@SerializedName("twitter_username")
@Expose
private String twitterUsername;
@SerializedName("portfolio_url")
@Expose
private String portfolioUrl;
@SerializedName("profile_image")
@Expose
private ProfileImage profileImage;
@SerializedName("links")
@Expose
private Links links;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getInstagramUsername() {
return instagramUsername;
}

public void setInstagramUsername(String instagramUsername) {
this.instagramUsername = instagramUsername;
}

public String getTwitterUsername() {
return twitterUsername;
}

public void setTwitterUsername(String twitterUsername) {
this.twitterUsername = twitterUsername;
}

public String getPortfolioUrl() {
return portfolioUrl;
}

public void setPortfolioUrl(String portfolioUrl) {
this.portfolioUrl = portfolioUrl;
}

public ProfileImage getProfileImage() {
return profileImage;
}

public void setProfileImage(ProfileImage profileImage) {
this.profileImage = profileImage;
}

public Links getLinks() {
return links;
}

public void setLinks(Links links) {
this.links = links;
}

}

下次尝试从此Link将JSON转换为POJO。

答案 1 :(得分:0)

我假设您的api响应是从这样的对象开始的:因此,再创建一个包含此arrayList of Photo的类。

所以您的错误说:应该是BEGIN_ARRAY,但是在第1行第2列路径$ BEGIN_OBJECT

 {
"photo":[
 "color":"#ffffff","width":"45cm"
 ]
}