从 URL 加载带有 JSON 数据的 ListView
Posted
技术标签:
【中文标题】从 URL 加载带有 JSON 数据的 ListView【英文标题】:Load ListView with JSON data from URL 【发布时间】:2014-09-20 10:49:10 【问题描述】:我有以下场景:
我开发了一个在 MainActivity 中有一个 ListView 的 android 应用程序 用于填充 ListView 的数据来自返回 JSON 数据的 URL 我想尽可能长时间地“缓存”ListView 项目(取决于 URL 资源的缓存控制标头),这意味着我不想每次都重新加载 ListView 数据(来自外部 URL)用户返回 MainActivity我发现这篇文章:Android AsyncTask ListView - JSON|Surviving w/ Android 这很好,但不是我想要的。我不想每次用户回到 MainActivity 时都执行 AsyncTask。
我想将 ListView 项目存储在应用程序的全局可用参数中。然后,此参数将是某种自定义容器,其中包含 ListItems 和它们过期的时间戳。如果 ListView 项目有效,则可以检查 AsyncTask 的“doInBackground”方法。如果是则返回,否则从 URL 加载并保存到全局变量中。
我的问题:这个解决方案有意义吗?你会如何解决这个问题?有什么想法可以让它变得更好吗?
【问题讨论】:
我认为当用户来到您的列表活动时,您已经检查了更新或最新的数据,这有两种可能性 1.如果第一次加载列表数据而不是用户必须等到从服务器加载数据并缓存在数据库和 2.检查来自服务器的最新或更新数据此检查在后台用户 ui 中运行不会阻止从本地缓存提供的此数据。 我不想在数据库中缓存 JSON 数据。我不需要持久存储数据。在每个应用程序启动时,我都会再次从 URL 下载数据。这是因为最新的原因。我也不需要将数据从 JSON 同步到数据库。这将是不必要的开销。 【参考方案1】:嗯,你的有道理;不过,我想补充一点。
对于编码部分,
每次请求成功完成时缓存 JSON。您可能需要使用应该在您的自定义Application
类中定义的 LruCache
。每个键/值对在解析 JSON 后存储数据模型。例如,cache.put(model.id, model)
。
对于用户体验部分,
您不需要每次都更新 JSON,而是提供一个操作触发器来执行此操作。一些常见的方法是:
在屏幕某处提供刷新按钮? (可能是ActionBar
...上的一个项目)
应用程序开始执行。
用户下拉ListView
刷新内容。
...
【讨论】:
感谢您的回答。显示的项目代表新闻项目。因此,我宁愿让应用程序进行更新。据我了解,用户不想更新新闻。他想在任何给定时间看到最新的新闻。 AsyncTask 总是启动并检查数据是否仍然有效,如果不是,它会提取新数据。因此用户无需更新。 至于 LruCache:使用 LruCache 代替全局可用的 Application 变量会明显更好吗?这有很大的不同吗? 好吧,就像在您的用例中那样,我个人倾向于使用Service
来检查最新消息,例如,每次检查 10 分钟。持续的请求会耗尽电池,就像我的经验一样,它会很快耗尽。
服务器上的JSON数据有一个缓存控制头,至少半小时有效。这反过来意味着 AsyncTask 在第一次从 URL 加载数据之后不需要拉新数据,因为它被缓存在应用程序中。所以我认为没有那么多电池消耗。
好吧,我不知道。你最好先试一试,看看它是如何工作的。【参考方案2】:
由于 ListView 数据在检索时已经序列化为 JSON,我认为最好的办法是保留 JSON。 Android 处理SharedPreferences 中的持久字符串。您还可以使用 SharedPreferences 来保持 keepalive 时间戳,从而让您确定何时应该刷新数据。
这将允许您在应用程序加载之间以及活动之间填充 ListView,而无需查询服务器。
【讨论】:
我不确定我是否喜欢将 JSON 数据存储在 SharedPreferences 中的想法。我认为这是糟糕的设计。我的第一个应用程序也这样做了,但我对这种行为不太满意。我宁愿使用全局应用程序变量来存储只需要在应用程序生命周期中可用的数据。【参考方案3】: var api=
getapicallForCategories()
var url='your url';
return fetch(url).then((res)=>res.json());
,
;
module.exports=api;
componentDidMount()
api.getapicallForCategories().then((res) =>
this.setState(
listdata: res,
)
);
//inside render
for (var m = 0; m < this.state.listdata.length; m++)
this.state.listdataCategory[m] = this.state.listdata[m].Category;
this.state.listdataPrice[m] = this.state.listdata[m].Amt;
const details =
name: this.state.listdataCategory[m],
price: this.state.listdataPrice[m],
list.push(details);
// inside return
list.map((l, i) => (
<ListItem
key=i
title=l.name
subtitle=l.price
rightIcon=<Icon name='add-circle' style= color: '#006400', fontSize: 40 onPress=() => this.onIncrease(l.price, i) />
avatar=<Icon name='remove-circle' style= color: '#FF0000', fontSize: 40 onPress=() => this.onRemove(l.price, i) />
/>
))
【讨论】:
以上是关于从 URL 加载带有 JSON 数据的 ListView的主要内容,如果未能解决你的问题,请参考以下文章
如何从 URL 解析带有 Windows Phone 8 中图像的 Json 数据?动态数据
带有Json文件的UITableView,将图像加载到单元格消失