无法使用 Retrofit 调用 GItHub 搜索用户 API
Cannot call GItHub search user API with Retrofit
我正在试验 GitHub search users API。我的目标是编写一个简单的应用程序:键入一个用户名,任何与之相关的 GitHub 用户名都会显示在 RecyclerView 上(使用 MVVM 模式)。
例如,这里是如何搜索用户名 clive:
https://api.github.com/search/users?q=clive
这里是代码的相关部分:
APIConfig.java
public class APIConfig {
public static final String BASE_URL = "https://api.github.com";
public static final String END_POINT_SEARCH_USERS = "/search/users";
}
APIEndPoint.java
import com.divbyzero.app.githubusersearch.model.User;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface APIEndPoint {
@GET(APIConfig.END_POINT_SEARCH_USERS)
Call<List<User>> getSearchResult(@Query("q") String param);
}
User.java
package com.divbyzero.app.githubusersearch.model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class User {
@SerializedName("login")
@Expose
private String login;
@SerializedName("avatar_url")
@Expose
private String avatar_url;
public void setLogin(String login){
this.login = login;
}
public void setAvatarUrl(String url){
this.avatar_url = url;
}
public String getLogin(){
return login;
}
public String getAvatarUrl(){
return avatar_url;
}
public User(String login, String url){
this.login = login;
this.avatar_url = url;
}
}
UserViewModel.java
package com.divbyzero.app.githubusersearch.viewmodel;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.divbyzero.app.githubusersearch.api.APIEndPoint;
import com.divbyzero.app.githubusersearch.api.APIService;
import com.divbyzero.app.githubusersearch.model.User;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class UserViewModel extends ViewModel {
private MutableLiveData<ArrayList<User>> mutableLiveData = new MutableLiveData<>();
public void setSearchResult(String param){
Retrofit retrofit = APIService.getRetrofitService();
APIEndPoint apiEndpoint = retrofit.create(APIEndPoint.class);
Call<List<User>> call = apiEndpoint.getSearchResult(param);
call.enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
mutableLiveData.setValue((ArrayList<User>) response.body());
Log.d("DBG", "OK");
}
@Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.d("DBG", "Failed");
}
});
}
public LiveData<ArrayList<User>> getSearchResult(){
return mutableLiveData;
}
}
完整源代码:https://github.com/anta40/GithubUserSearch
当我在 SearchView 上键入任何用户名并按下 ENTER 键时,没有显示任何搜索结果(recyclerview 仍然是空的)。进一步检查后,我发现 "DBG: Failed" 显示在 logcat 上,这意味着 GitHub API 没有正确调用。如何解决这个问题?
错误
您的视图模型中出现的错误是:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
所以解析您的回复时出现问题。您正在接收它,但解析错误。
原因
调用此 GET 请求(您正在使用)后:
https://api.github.com/search/users?q=some_name
我收到:
{
"total_count": 0,
"incomplete_results": false,
"items": [
]
}
哪里有问题
基于收到 .json
我明白了,作为根元素的是 JSON OBJECT。在您的 ViewModel 中,您期望 List<User>
(JSON ARRAY) 这是不正确的。您正在接收包含 3 个字段的对象。此字段之一是您的 List<User>
.
修复 - 说明
您必须创建新模型 class 来描述您正在接收的数据。要解析(从json到Java)所有接收到的接收数据,它应该包含3个字段。
修复 - 代码
你的新例子class:
public class GitHubResponse {
private long totalCount;
private boolean incompleteResults;
private List<User> items;
}
并在 ViewModel 和 APIEndPoint.java
的每个地方使用这个 class。访问数据 - 此 class.
的广告获取者
一般项目hints/tips
重新格式化代码 (Ctrl + Alt + L)
添加“开始”状态(因为启动后应用视图是空的)
添加空状态(接收数据为空时)
添加加载状态(加载数据等待响应时)
添加错误状态(当连接失败或解析数据出现问题时)
我正在试验 GitHub search users API。我的目标是编写一个简单的应用程序:键入一个用户名,任何与之相关的 GitHub 用户名都会显示在 RecyclerView 上(使用 MVVM 模式)。
例如,这里是如何搜索用户名 clive:
https://api.github.com/search/users?q=clive
这里是代码的相关部分:
APIConfig.java
public class APIConfig {
public static final String BASE_URL = "https://api.github.com";
public static final String END_POINT_SEARCH_USERS = "/search/users";
}
APIEndPoint.java
import com.divbyzero.app.githubusersearch.model.User;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface APIEndPoint {
@GET(APIConfig.END_POINT_SEARCH_USERS)
Call<List<User>> getSearchResult(@Query("q") String param);
}
User.java
package com.divbyzero.app.githubusersearch.model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class User {
@SerializedName("login")
@Expose
private String login;
@SerializedName("avatar_url")
@Expose
private String avatar_url;
public void setLogin(String login){
this.login = login;
}
public void setAvatarUrl(String url){
this.avatar_url = url;
}
public String getLogin(){
return login;
}
public String getAvatarUrl(){
return avatar_url;
}
public User(String login, String url){
this.login = login;
this.avatar_url = url;
}
}
UserViewModel.java
package com.divbyzero.app.githubusersearch.viewmodel;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.divbyzero.app.githubusersearch.api.APIEndPoint;
import com.divbyzero.app.githubusersearch.api.APIService;
import com.divbyzero.app.githubusersearch.model.User;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class UserViewModel extends ViewModel {
private MutableLiveData<ArrayList<User>> mutableLiveData = new MutableLiveData<>();
public void setSearchResult(String param){
Retrofit retrofit = APIService.getRetrofitService();
APIEndPoint apiEndpoint = retrofit.create(APIEndPoint.class);
Call<List<User>> call = apiEndpoint.getSearchResult(param);
call.enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
mutableLiveData.setValue((ArrayList<User>) response.body());
Log.d("DBG", "OK");
}
@Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.d("DBG", "Failed");
}
});
}
public LiveData<ArrayList<User>> getSearchResult(){
return mutableLiveData;
}
}
完整源代码:https://github.com/anta40/GithubUserSearch
当我在 SearchView 上键入任何用户名并按下 ENTER 键时,没有显示任何搜索结果(recyclerview 仍然是空的)。进一步检查后,我发现 "DBG: Failed" 显示在 logcat 上,这意味着 GitHub API 没有正确调用。如何解决这个问题?
错误
您的视图模型中出现的错误是:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
所以解析您的回复时出现问题。您正在接收它,但解析错误。
原因
调用此 GET 请求(您正在使用)后:
https://api.github.com/search/users?q=some_name
我收到:
{
"total_count": 0,
"incomplete_results": false,
"items": [
]
}
哪里有问题
基于收到 .json
我明白了,作为根元素的是 JSON OBJECT。在您的 ViewModel 中,您期望 List<User>
(JSON ARRAY) 这是不正确的。您正在接收包含 3 个字段的对象。此字段之一是您的 List<User>
.
修复 - 说明
您必须创建新模型 class 来描述您正在接收的数据。要解析(从json到Java)所有接收到的接收数据,它应该包含3个字段。
修复 - 代码
你的新例子class:
public class GitHubResponse {
private long totalCount;
private boolean incompleteResults;
private List<User> items;
}
并在 ViewModel 和 APIEndPoint.java
的每个地方使用这个 class。访问数据 - 此 class.
一般项目hints/tips
重新格式化代码 (Ctrl + Alt + L)
添加“开始”状态(因为启动后应用视图是空的)
添加空状态(接收数据为空时)
添加加载状态(加载数据等待响应时)
添加错误状态(当连接失败或解析数据出现问题时)