数据未添加到 list.add

Posted

技术标签:

【中文标题】数据未添加到 list.add【英文标题】:Data is not added to list.add 【发布时间】:2019-03-18 08:56:40 【问题描述】:

数据未添加到列表中。该程序从 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());
                    
                
            

【问题讨论】:

entry.status() 是字符串类型吗? 不,它是自定义状态类型 使用 if 循环代替 switch 尝试可能会在 switch 语句中与字符串发生冲突,并且可能是基于开发要求的自定义类型。 它没有用。 if 语句 如果列表为空检查entry对象是否有值,则有任何错误或您的列表仍为空。 【参考方案1】:

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

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

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

希望这会有所帮助!!

【讨论】:

抱歉回复晚了。 notifyDataSetChanged 是做什么用的? 用于在数据发生变化时刷新recylerView,通常用于绑定数据列表到View(***.com/questions/3669325/…) 感谢您的回答。另一个与问题无关的问题是如何加载数据。据我现在所知,它是通过有一个视图来显示数据,有一个适配器来设置数据并有另一个类来加载数据。对于这个项目,我使用的是 GridView。 查看Android文档中的数据绑定,他们将为您提供详细的解释。 (developer.android.com/topic/libraries/data-binding)。如果您觉得此答案有用,请将此答案标记为正确。如果您需要进一步的支持,您可以创建另一个问题并标记我:) 看来你是正确的,它是异步的。感谢您的帮助!

以上是关于数据未添加到 list.add的主要内容,如果未能解决你的问题,请参考以下文章

一个list怎么添加另一个list中

java里有没有专门判断List里有重复的数据

java中 list怎么去除多条数据?

java把一个list里的数据转移到另外一个list

List.Add 正在替换索引 0 而不是添加到下一个位置。为啥?

把一个list里的元素增加到另一个list中