首页 > 解决方案 > 数据未添加到 list.add

问题描述

数据不会添加到列表中。该程序从 GraphQL 服务器获取数据并通过 switch 语句对其进行过滤,然后将其附加到相应的列表中。但是,如果在 switch 语句之外访问,则该列表为空。如果您在 switch 语句中打印列表之一,它将正确打印,但是如果您在 getter 函数中打印它,它将不会返回任何内容。

它有什么问题?范围?我尝试将初始化放在几个地方,比如在同一个函数或构造函数上,但结果是一样的。

package sukebei.anilog.data.source.AniList;

import android.util.Log;

import com.apollographql.apollo.ApolloCall;
import com.apollographql.apollo.ApolloClient;
import com.apollographql.apollo.api.Response;
import com.apollographql.apollo.exception.ApolloException;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

import okhttp3.OkHttpClient;

import AniList.UserMediaQuery;
import AniList.UserMediaQuery.Data;
import AniList.type.MediaType;

/*  Data Received Example

[
    Entry {
        __typename = MediaList, 
        progress = 0, 
        progressVolumes = null, 
        score = 0.0, 
        status = PLANNING, 
        notes = null, 
        repeat = 0, 
        media = Media {
            __typename = Media, 
            chapters = null, 
            volumes = null, 
            idMal = 17082, 
            episodes = 12, 
            title = Title {
                __typename = MediaTitle, romaji = Aiura
            }
        }
    }, 
    Entry {
        __typename = MediaList, 
        progress = 0, 
        progressVolumes = null, 
        score = 0.0, 
        status = PLANNING, 
        notes = null, 
        repeat = 0, 
        media = Media {
            __typename = Media, 
            chapters = null, 
            volumes = null, 
            idMal = 33218, 
            episodes = 1, 
            title = Title {
            __typename = MediaTitle, 
            romaji = Kimi no Koe wo Todoketai
            }
        }
    }
]
*/


public class AniList {
    private static final String BASE_URL = "https://graphql.anilist.co";

    private List<UserMediaQuery.Entry> planningMedia = new ArrayList<UserMediaQuery.Entry>();
    private List<UserMediaQuery.Entry> currentMedia = new ArrayList<UserMediaQuery.Entry>();
    private List<UserMediaQuery.Entry> completedMedia = new ArrayList<UserMediaQuery.Entry>();
    private List<UserMediaQuery.Entry> droppedMedia = new ArrayList<UserMediaQuery.Entry>();
    private List<UserMediaQuery.Entry> pausedMedia = new ArrayList<UserMediaQuery.Entry>();
    private List<UserMediaQuery.Entry> repeatingMedia = new ArrayList<UserMediaQuery.Entry>();

    private OkHttpClient okHttpClient;
    private ApolloClient apolloClient;

    public AniList() {
        okHttpClient = new OkHttpClient.Builder().build();
        apolloClient = ApolloClient.builder()
            .serverUrl(BASE_URL)
            .okHttpClient(okHttpClient)
            .build();
    }

    public void loadUserData(String username, MediaType mediaType) {

        UserMediaQuery mediaQuery = UserMediaQuery.builder()
                                        .username(username)
                                        .type(mediaType)
                                        .build();

        apolloClient.query(mediaQuery).enqueue(new ApolloCall.Callback<Data>() {
                @Override public void onResponse(@NotNull Response<Data> dataResponse) {
                    for (UserMediaQuery.List data : dataResponse.data().userMediaList().lists()) {
                        for (UserMediaQuery.Entry entry: data.entries()) {
                            switch(entry.status()) {
                                case PLANNING:
                                    planningMedia.add(entry);
                                    break;
                                case CURRENT:
                                    currentMedia.add(entry);
                                    break;
                                case COMPLETED:
                                    completedMedia.add(entry);
                                    break;
                                case DROPPED:
                                    droppedMedia.add(entry);
                                    break;
                                case PAUSED:
                                    pausedMedia.add(entry);
                                    break;
                                case REPEATING:
                                    repeatingMedia.add(entry);
                                    break;
                            }
                        }
                    }
                }

                @Override
                public void onFailure(@NotNull ApolloException t) {
                    Log.e("AniList Source", t.getMessage(), t);
                }
            }
        );
    }

    public List getPlanningMedia() {
        return planningMedia;
    }


    public List getCurrentMedia() {
        return currentMedia;
    }


    public List getCompletedMedia() {
        return completedMedia;
    }


    public List getDroppedMedia() {
        return droppedMedia;
    }


    public List getPausedMedia() {
        return pausedMedia;
    }

    public List getRepeatingMedia() {
        return repeatingMedia;
    }
}

这会打印数据,但是当您在 getter 函数中打印数据时,它不会打印数据。

            for (UserMediaQuery.List data : dataResponse.data().userMediaList().lists()) {
                for (UserMediaQuery.Entry entry: data.entries()) {
                    if (entry.status() == MediaListStatus.PLANNING) {
                        planningMedia.add(entry);
                        Log.d("planning", planningMedia.toString());
                    }
                }
            }

标签: javaandroidarraysapollo

解决方案


apolloClient.query(mediaQuery).enqueue异步执行代码,这意味着它将请求排入队列,因此数组列表将为空,直到请求完成并从另一个线程成功。

您可能直接使用 getter 而无需等待回调完成。如果是这种情况,请查看以下可能的解决方案。

如果您正在等待请求完成以在您的 UI 上显示某些内容,您可能希望通过使用类似notifyDataSetChanged()in case 的方式再次将数据绑定到 UI RecyclerView。同样,如果您想将此数据用于其他用途,您可能应该使用回调机制。

希望这可以帮助 !!


推荐阅读