我已经在listview
中解析了JSON数据,现在我想让它脱机使用。
有没有办法在手机上保存JSON数据,以便在手机离线时可以看到数据?
有人知道一个例子吗?
编辑现在可以使用:
public class MainActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new TheTask().execute();
}
class TheTask extends AsyncTask<Void, Void, JSONArray> {
InputStream is = null;
String result = "";
JSONArray jArray = null;
ProgressDialog pd;
@Override
protected void onPostExecute(JSONArray result) {
super.onPostExecute(result);
pd.dismiss();
ArrayList<String> list= new ArrayList<String>();
try {
for(int i=0;i<result.length();i++) {
JSONObject jb = result.getJSONObject(i) ;
String name = jb.getString("name")+" "+jb.getString("Art");
list.add(name);
}
} catch(Exception e) {
e.printStackTrace();
}
setListAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, list));
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pd = ProgressDialog.show(MainActivity.this, "State",
"Loading...", true);
}
@Override
protected JSONArray doInBackground(Void... arg0) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("***");
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// Convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
writeToFile(result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
try {
jArray = new JSONArray(result);
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
try {
jArray = new JSONArray(readFromFile());
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
return jArray;
}
}
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
private String readFromFile() {
String ret = "";
try {
InputStream inputStream = openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
} catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
}
答案 0 :(得分:15)
你有两种方法。要么创建数据库并将所有数据保存在那里,并在需要时将其检索回来。或者,如果您拥有的数据不是那么多并且您不想处理数据库,那么您将json字符串写入存储卡中的文本文件,并在以后离线时读取它。
对于第二种情况,每次上网时,您都可以从Web服务中检索相同的json,然后将其写入旧的json。这样,您可以确保将最新的json保存到设备中。
答案 1 :(得分:3)
此类将帮助您使用密钥缓存文件中的字符串,以便稍后检索。字符串可以是json字符串,key可以是您请求的url,如果使用post方法,也可以是url的标识符。
public class CacheHelper {
static int cacheLifeHour = 7 * 24;
public static String getCacheDirectory(Context context){
return context.getCacheDir().getPath();
}
public static void save(Context context, String key, String value) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(cache));
out.writeUTF(value);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void save(Context context, String key, String value, String identifier) {
save(context, key + identifier, value);
}
public static String retrieve(Context context, String key, String identifier) {
return retrieve(context, key + identifier);
}
public static String retrieve(Context context, String key) {
try {
key = URLEncoder.encode(key, "UTF-8");
File cache = new File(getCacheDirectory(context) + "/" + key + ".srl");
if (cache.exists()) {
Date lastModDate = new Date(cache.lastModified());
Date now = new Date();
long diffInMillisec = now.getTime() - lastModDate.getTime();
long diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMillisec);
diffInSec /= 60;
diffInSec /= 60;
long hours = diffInSec % 24;
if (hours > cacheLifeHour) {
cache.delete();
return "";
}
ObjectInputStream in = new ObjectInputStream(new FileInputStream(cache));
String value = in.readUTF();
in.close();
return value;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
如何使用它:
String string = "cache me!";
String key = "cache1";
CacheHelper.save(context, key, string);
String getCache = CacheHelper.retrieve(context, key); // will return 'cache me!'
答案 2 :(得分:0)
下载数据后,您可以使用您喜欢的数据库或系统将数据保存在移动设备上。
您可以在此处查看不同的选项:data-storage
答案 3 :(得分:0)
您可以使用这两种方法将JSON
个文件存储为SharedPreferences
中的字符串并将其检索回来:
public String getStringProperty(String key) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
String res = null;
if (sharedPreferences != null) {
res = sharedPreferences.getString(key, null);
}
return res;
}
public void setStringProperty(String key, String value) {
sharedPreferences = context.getSharedPreferences("preferences", Activity.MODE_PRIVATE);
if (sharedPreferences != null) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
CupsLog.i(TAG, "Set " + key + " property = " + value);
}
}
只需使用setStringProperty("json", "yourJsonString")
保存并getStringProperty("json")
进行检索。
答案 4 :(得分:0)
使用SharedPreferences应该准备sqlite(除非你有一个数据库结构)。对于缓存和存储从互联网上提取的数据,我建议使用robospice:https://github.com/octo-online/robospice。它是一个非常完善的库,易于使用,应该在您从Internet下载数据或长时间运行任务时使用。
答案 5 :(得分:0)
如何将Json数据缓存到离线状态?
您可以使用gson更轻松地解析JSON数据。 在build.gradle文件中添加此依赖项。
compile 'com.google.code.gson:gson:2.8.0'
然后创建一个POJO类来解析JSON数据。
示例POJO类:
public class AppGeneralSettings {
@SerializedName("key1")
String data;
public String getData() {
return data;
}
}
要解析来自互联网的json字符串,请使用此代码段
AppGeneralSettings data=new Gson().fromJson(jsonString, AppGeneralSettings.class);
然后添加一个辅助类来存储和从首选项中检索JSON数据。
示例:用于存储数据的助手类
public class AppPreference {
private static final String FILE_NAME = BuildConfig.APPLICATION_ID + ".apppreference";
private static final String APP_GENERAL_SETTINGS = "app_general_settings";
private final SharedPreferences preferences;
public AppPreference(Context context) {
preferences = context.getSharedPreferences(FILE_NAME, MODE_PRIVATE);
}
public SharedPreferences.Editor setGeneralSettings(AppGeneralSettings appGeneralSettings) {
return preferences.edit().putString(APP_GENERAL_SETTINGS, new Gson().toJson(appGeneralSettings));
}
public AppGeneralSettings getGeneralSettings() {
return new Gson().fromJson(preferences.getString(APP_GENERAL_SETTINGS, "{}"), AppGeneralSettings.class);
}
}
保存数据
new AppPreference().setGeneralSettings(appGeneralSettings).commit();
检索数据
AppGeneralSettings appGeneralSettings = new AppPreference().getGeneralSettings();
答案 6 :(得分:0)
您可以缓存您的Retrofit响应,因此,当您第二次发出相同请求时,Retrofit将从缓存中获取该请求: https://medium.com/@coreflodev/understand-offline-first-and-offline-last-in-android-71191e92b426,https://futurestud.io/tutorials/retrofit-2-activate-response-caching-etag-last-modified。之后,您需要再次解析该json