我正在使用从服务器获取的数据(文本,图像URL等)填充列表视图。 此数据可能每周/每月在服务器端更新。 我想要的是,* 当我的应用程序第一次加载listview时,从服务器获取的数据存储在应用程序/客户端,以便稍后在重新绘制listview时重复使用。 *如何能否实现这一点。
一种可能的解决方案是:
有关使用Loaders / Loading Manager的任何观点。
修改
问题中的数据是jsonpackage。结构类似(考虑数组大小最大为100)
[ // JSON Array
{ // JSON Object
"rank":1,"country":"China",
"population":"1,354,040,000",
"flag":"http://www.androidbegin.com/tutorial/flag/china.png"
}, (
]
答案 0 :(得分:0)
是的,您需要将从服务器获取的数据存储到数据库本身,然后将数据从SQLiteDatabase
绑定到ListView
不能说每次要绘制列表视图时都要查询db,这不是一个好习惯.. ,因为你需要在活动开始时或者当活动时只获取一次数据数据库中的数据已更改。
重新使用已从服务器获取的数据... 意味着您需要持久存储,并且应定期或根据某些用户请求更新存储。
答案 1 :(得分:0)
这取决于您拥有的数据类型。通常,如果它来自服务器的json包,那么你可以保留原始的json并解析并填充每个应用程序启动时的数据。但是,只有当数据量不太大时,这才有用。如果您在任何给定时刻的数据量很大,那么您将需要解析并将格式化数据存储到SQL DB,查询并在每次应用程序启动时获取数据。
此外,在可管理的数据量的情况下,您可以使用静态数据模型实例在应用程序生命周期的持续时间内将数据保留在内存中。
您可以通过多种方式解决此问题,但这一切都取决于您拥有多少数据以及采用何种格式,因此您可以调用哪种方法可以获得最佳性能。
答案 2 :(得分:0)
使用此静态方法在sdcard / internal storage中创建一个目录。
/**
* Cache class to create dir, save, retrieve and delete files
* File names are hashCode of the url json is downloaded from.
**/
public class FileCache {
static File cacheDir;
static final String DIRECTORY_ADDRESS = "/Android/data/<app_package>/.<directory name>";
public static createDirectory(Context context){
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(Environment.getExternalStorageDirectory(),DIRECTORY_ADDRESS);
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}
public static File getFile(String url){
String filename=String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
return f;
}
public static void saveFile(InputStream is, File file){
try {
OutputStream os = new FileOutputStream(file);
copyStream(is, os);
os.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
/**
* Clear all files at app uninstall or application or on
* low memory or some other event, using a boradcastreceiver/alarmmanager
**/
public static void clear(){
File[] files=cacheDir.listFiles();
if(files==null)
return;
for(File f:files)
f.delete();
}
}
现在在应用程序启动时创建目录:
FileCache.createDirectory(context);
设置完成后,您必须使用AsyncTask获取JSONArray,将其存储在文件中
/**
* Add this in doinBackground()
**/
private File getJson(Stirng url) {
File f = FileCache.getFile(url);
if(f != null && f.isFile()) {
//file exists in directory, no need to download.
return f;
}
try {
URL fileUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) fileUrl.openConnection();
conn.setConnectTimeout(120000);
conn.setReadTimeout(120000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
FileCache.saveFile(is, f);
return f;
} catch (Exception ex) {
return null;
}
}
现在,每次需要加载数据并将数据绑定到listview时,都必须运行此线程。我将排除有关如何从文件解析json并将其转换为适配器列表的详细信息。
如果在文件中不可用,此AsyncTask将自动获取数据,并在onPostExecute()中加载到listview中。因此,从第二次起,它不会花费太多时间,数据将保留在存储中。您还可以在ListView中添加分页,即如果您有1000个json哈希值,则可以批量读取此文件中的数据,这也是一个很好的优化。
现在,每当数据更新(每月/每周)时,使用GCM发送推送通知,运行服务,使用FileCache.clear()清除旧文件,并从服务启动此AsyncTask,所有这些都在后台运行,如果之后打开应用程序,您将从文件存储中获取更新数据。
将所有内容放在sqlite中是一个类似的选择,然后你必须使用DbAdapters,CursorLoaders和CursorAdapters,然后使用该服务来更新db。
但是由于你没有大型数据集,我认为文件缓存就足够了。
希望有所帮助。 :)
答案 3 :(得分:0)
我实现如下:
(如果您在实施中发现任何问题,表现明智或任何请发表评论)
到目前为止,这种方法运作良好。你们看到我在任何阶段都可以面对任何问题。 THANKYOU