数据未添加到 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的主要内容,如果未能解决你的问题,请参考以下文章