java - 使用 Retrofit2 调用 API 时无法接收数据

标签 java android gson retrofit2

我正在制作一个简单的应用程序,它必须调用一个 API,该 API 返回一个具有某些属性的对象并显示在 RecyclerView 中。

正在调用https://jsonplaceholder.typicode.com/photos?_start=0&_limit=5

应用程序没有崩溃,正在生成回收器 View ,但它是空的。我使用调试器看到recyclerview的适配器中的列表是空的(大小为0)。

我相信问题出在我制作的java对象的结构上,但我无法确定它,而且我似乎无法修改我的对象结构以匹配返回对象的结构。我没有看到一个对象内部有其他对象,就像我处理过的其他 api 一样(当我使用 json 在线阅读器检查上面的链接时)。

我通常创建我的对象和另一个对象容器(其中包含第一个对象的列表)。我怀疑问题就在那里,请帮我找出问题所在。 下面主要是activity、对象、对象容器、适配器、retrofit对象、对象dao和对象 Controller 。

Activity :

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);
    }
}

对象DAO

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) {

            }
        });

    }
}

对象 Controller

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 对象JSON 数组getPhotos 方法应与 getAlbum 方法类似。尝试:

public void getPhotos(String fixedUrl, final ResultListener<List<MyPhoto>> listenerOfTheView)

关于java - 使用 Retrofit2 调用 API 时无法接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683454/

相关文章:

java - 改造 : How to decide the class members?

java - 使用 GSON 和 TypeAdapter 将 BSON (mongoDB) 读入 POJO

java - GSON 抛出 Expected BEGIN_ARRAY but was BEGIN_OBJECT 错误

java - 启动时出现 Eclipse Logback 错误

android - 获取微调器选定项目文本?

Java FileNotFoundException 尽管文件存在。

java - 找不到参数的compileOptions()方法

java - 有没有办法在 Java 8 中将 ZoneId 转换为 ZoneOffset?

java - JNI "env->GetStaticMethodID()"程序崩溃

java - 在 Java 应用程序中执行 XQuery 中的命令 block