首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将JSON解析为脱机使用

如何将JSON解析为脱机使用
EN

Stack Overflow用户
提问于 2015-01-14 11:35:11
回答 2查看 5.1K关注 0票数 5

我已经成功地解析了JSON,但是现在我想缓存它以供脱机使用,甚至internet都不可用,如果有任何新条目出现,我也想缓存它。

缓存数据的最佳选择是什么?SharedPreferencesSQLite database

下面是我的代码,用于分析JSON:

代码语言:javascript
复制
public class MainActivity extends Activity {

    ArrayList<Actors> actorsList;   
    ActorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        actorsList = new ArrayList<Actors>();
        new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors");

        ListView listview = (ListView)findViewById(R.id.list);
        adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);

        listview.setAdapter(adapter);

        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long id) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();              
            }
        });
    }


    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Loading, please wait");
            dialog.setTitle("Connecting server");
            dialog.show();
            dialog.setCancelable(false);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {

                //------------------>>
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);

                // StatusLine stat = response.getStatusLine();
                int status = response.getStatusLine().getStatusCode();

                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);


                    JSONObject jsono = new JSONObject(data);
                    JSONArray jarray = jsono.getJSONArray("actors");

                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        Actors actor = new Actors();

                        actor.setName(object.getString("name"));
                        actor.setDescription(object.getString("description"));

                        actorsList.add(actor);
                    }
                    return true;
                }

                //------------------>>

            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            adapter.notifyDataSetChanged();
            if(result == false)
                Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();

        }
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-29 12:57:02

为什么不使用这样的方法将其保存到应用程序的缓存文件夹中:

代码语言:javascript
复制
String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
    dir.mkdirs();
}
path += "data";
File data = new File(path);
if (!data.createNewFile()) {
    data.delete();
    data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(actorsList);
objectOutputStream.close();

在此之后,您可以在任何时候使用:

代码语言:javascript
复制
List<?> list = null;
File data = new File(path);
try {
    if(data.exists()) {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
        list = (List<Object>) objectInputStream.readObject();
        objectInputStream.close();
    }
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

更新:好,使类名为ObjectToFileUtil,将此代码粘贴到创建的类中

代码语言:javascript
复制
package <yourpackagehere>;

import android.os.Environment;

import java.io.*;

public class ObjectToFileUtil {

    public static String objectToFile(Object object) throws IOException {
        String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        path += "data";
        File data = new File(path);
        if (!data.createNewFile()) {
            data.delete();
            data.createNewFile();
        }
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        return path;
    }

    public static Object objectFromFile(String path) throws IOException, ClassNotFoundException {
        Object object = null;
        File data = new File(path);
        if(data.exists()) {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
            object = objectInputStream.readObject();
            objectInputStream.close();
        }
        return object;
    }
}

将< yourpackagehere >更改为您的包名,并且不要忘记向WRITE_EXTERNAL_STORAGE添加AndroidManifest.xml.权限在您的MainActivity添加字段中

代码语言:javascript
复制
private String dataPath;

并将onPostExecute类的JSONAsyncTask方法替换为

代码语言:javascript
复制
protected void onPostExecute(Boolean result) {
    dialog.cancel();
    adapter.notifyDataSetChanged();
    if(result) {
        try {
            dataPath = objectToFile(arrayList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
    }
}

现在,您可以在任何时候从文件中访问actorsList,方法是

代码语言:javascript
复制
try {
    actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

如果要在关闭应用程序后保存文件路径,则必须保存dataPath字符串(并在应用程序启动时加载),例如,使用SharedPreferences

票数 8
EN

Stack Overflow用户

发布于 2015-01-14 12:45:55

代码语言:javascript
复制
And what would be the best option to cache data ? SharedPreferences or SQLite database

这完全是基于你收到的数据。

  1. 如果数据是小的,非结构化数据,那么使用共享Pref
  2. 如果数据很大,则使用SQLite

但是为了更好地存储完整的数据,您可以使用档案概念。将字符串数据存储在代码String data = EntityUtils.toString(entity);中,您必须将来自服务器的数据中的任何更改保存到file.If中,如果没有internet,则将其添加到file.And中检索数据。从上面的链接获取文件操作的示例代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27941986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档