java - 使用 Retrofit2 调用 API 时无法接收数据
问题描述
我正在制作一个简单的应用程序,该应用程序必须调用一个 API,该 API 返回具有某些属性的对象并显示在 RecyclerView 中。
正在调用https://jsonplaceholder.typicode.com/photos?_start=0&_limit=5
该应用程序没有崩溃,正在生成recyclerview,但它是空的。使用调试器,看到recyclerview的adapter中的list是空的(大小为0)。
我相信问题出在我制作的 java 对象的结构上,但我无法确定,而且我似乎无法修改我的对象结构以匹配返回对象的结构。我没有看到一个包含其他对象的对象,就像我研究过的其他 api 一样(当我使用 json 在线阅读器检查上面的链接时)。
我通常制作我的对象和另一个对象容器(其中包含第一个对象的列表)。我的怀疑是问题在那里,请帮助我找到问题。下面主要是activity、object、object container、adapter、retrofit object、object dao和object controller。
活动:
public class PhotoActivity extends AppCompatActivity implements AdapterPhotoRecyclerView.SelectedPhotoListener {
private AdapterPhotoRecyclerView adapterPhotoRecyclerView;
private RecyclerView recyclerView;
private ProgressBar progressBar;
private LinearLayoutManager linearLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
progressBar = findViewById(R.id.photo_activity_progress_bar);
makeCall("photos?_start=0&_limit=5");
adapterPhotoRecyclerView = new AdapterPhotoRecyclerView(this);
recyclerView = findViewById(R.id.photo_activity_recyclerview);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapterPhotoRecyclerView);
}
public void makeCall(String fixedUrl) {
MyPhotoController myPhotoController = new MyPhotoController();
myPhotoController.getPhotos(fixedUrl, new ResultListener<MyPhotoContainer>() {
@Override
public void finish(MyPhotoContainer result) {
progressBar.setVisibility(View.VISIBLE);
adapterPhotoRecyclerView.setMyPhotoList(result.getmPhotoList());
progressBar.setVisibility(View.GONE);
}
});
}
@Override
public void selectePhoto(Integer position, List<MyPhoto> myPhotoList) {
MyPhoto clickedPhoto = myPhotoList.get(position);
Toast.makeText(this, clickedPhoto.getTitle(), Toast.LENGTH_SHORT).show();
}
}
RecyclerView 的适配器
public class AdapterPhotoRecyclerView extends RecyclerView.Adapter<AdapterPhotoRecyclerView.PhotoViewHolder> {
private List<MyPhoto> myPhotoList;
private SelectedPhotoListener selectedPhotoListener;
public AdapterPhotoRecyclerView(SelectedPhotoListener selectedPhotoListener) {
myPhotoList = new ArrayList<>();
this.selectedPhotoListener = selectedPhotoListener;
}
public void setMyPhotoList(List<MyPhoto> myPhotoList) {
this.myPhotoList = myPhotoList;
notifyDataSetChanged();
}
public List<MyPhoto> getMyPhotoList() {
return myPhotoList;
}
@NonNull
@Override
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_cell_photo, parent, false);
PhotoViewHolder photoViewHolder = new PhotoViewHolder(view);
return photoViewHolder;
}
@Override
public void onBindViewHolder(@NonNull PhotoViewHolder holder, int position) {
MyPhoto myPhoto = myPhotoList.get(position);
holder.bindPhoto(myPhoto);
}
@Override
public int getItemCount() {
if (myPhotoList == null){
return 0;
} else {
return myPhotoList.size();
}
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView thumbnail;
private TextView title;
public PhotoViewHolder(@NonNull View itemView) {
super(itemView);
this.thumbnail = itemView.findViewById(R.id.recyclerview_cell_photo_thumbnail);
this.title = itemView.findViewById(R.id.recyclerview_cell_photo_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectedPhotoListener.selectePhoto(getAdapterPosition(), myPhotoList);
}
});
}
public void bindPhoto(MyPhoto myPhoto) {
Glide.with(itemView).load(myPhoto.getThumbnailUrl()).placeholder(R.mipmap.ic_launcher).into(thumbnail);
title.setText(myPhoto.getTitle());
}
}
public interface SelectedPhotoListener {
public void selectePhoto(Integer position, List<MyPhoto> myPhotoList);
}
}
对象道
public class MyPhotoDao extends MyRetrofit {
private JsonPlaceholderService service;
public MyPhotoDao() {
super("https://jsonplaceholder.typicode.com/");
service = retrofit.create(JsonPlaceholderService.class);
}
public void getPhotos(String fixedUrl, final ResultListener<MyPhotoContainer> listenerOfTheController) {
Call<MyPhotoContainer> call = service.jsonPlaceholderPhoto(fixedUrl);
call.enqueue(new Callback<MyPhotoContainer>() {
@Override
public void onResponse(Call<MyPhotoContainer> call, Response<MyPhotoContainer> response) {
MyPhotoContainer myPhotoContainer = response.body();
listenerOfTheController.finish(myPhotoContainer);
}
@Override
public void onFailure(Call<MyPhotoContainer> call, Throwable t) {
}
});
}
public void getAlbum(String fixedUrl, final ResultListener<List<Album>> listenerOfTheController){
Call<List<Album>> call = service.jsonPlaceholderAlbum(fixedUrl);
call.enqueue(new Callback<List<Album>>() {
@Override
public void onResponse(Call<List<Album>> call, Response<List<Album>> response) {
List<Album> albumList = response.body();
listenerOfTheController.finish(albumList);
}
@Override
public void onFailure(Call<List<Album>> call, Throwable t) {
}
});
}
}
对象控制器
public class MyPhotoController {
public void getPhotos(String fixedUrl, final ResultListener<MyPhotoContainer> listenerOfTheView) {
MyPhotoDao myPhotoDao = new MyPhotoDao();
myPhotoDao.getPhotos(fixedUrl, new ResultListener<MyPhotoContainer>() {
@Override
public void finish(MyPhotoContainer result) {
listenerOfTheView.finish(result);
}
});
}
public void getAlbums(String fixedUrl, final ResultListener<List<Album>> listenerOfTheView){
MyPhotoDao myPhotoDao = new MyPhotoDao();
myPhotoDao.getAlbum(fixedUrl, new ResultListener<List<Album>>() {
@Override
public void finish(List<Album> result) {
listenerOfTheView.finish(result);
}
});
}
}
改造对象
public abstract class MyRetrofit {
protected Retrofit retrofit;
public MyRetrofit(String baseUrl) {
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create());
retrofit = builder.build();
}
}
我正在尝试获取的对象
public class MyPhoto implements Serializable {
@SerializedName("AlbumId")
private Integer albumNumber;
@SerializedName("id")
private Integer photoId;
private String title;
@SerializedName("url")
private String photoUrl;
private String thumbnailUrl;
public Integer getAlbumNumber() {
return albumNumber;
}
public Integer getPhotoId() {
return photoId;
}
public String getTitle() {
return title;
}
public String getPhotoUrl() {
return photoUrl;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
}
对象容器
public class MyPhotoContainer implements Serializable {
@SerializedName("array")
private List<MyPhoto> mPhotoList;
public List<MyPhoto> getmPhotoList() {
return mPhotoList;
}
}
如果有什么遗漏,请告诉我。任何帮助和评论都非常感谢!
解决方案
JSON
有效载荷不适合POJO
类。您根本不需要使用MyPhotoContainer
类。响应JSON
是一个JSON Array
直接放置JSON Object
的s。getPhotos
方法应该看起来类似于getAlbum
方法。尝试:
public void getPhotos(String fixedUrl, final ResultListener<List<MyPhoto>> listenerOfTheView)
推荐阅读
- javascript - 由于错误冲突,未创建 HTML 报告。reduce 不是函数
- flutter-dependencies - 无法确定任务 ':enx_flutter_plugin:compileDebugAidl' 的依赖关系
- kotlin - How is blocking in a suspend function different than calling an async function?
- c++ - 将 std::async 用于内部线程内的后台任务是否正确(而不是来自主进程的线程)
- java - Couchbase 使用 Reactive Flux 批量获取文档
- mysql - SQL Select 语句获取字符串中包含一个或多个值的所有记录
- java - 无法在 Android 客户端和 Node.js socket.io 服务器之间进行通信
- python - 尝试在树莓派上使用 wxPython
- csv - 如何在 Python 中使用预训练的 BERT 问答模型进行文本提取?
- node.js - 如何在一个房间中添加多个用户,例如节点 js 中的 whatsapp 组?