The best way to caching json
Asked Answered
B

4

15

My application should work not only in online but also in offline mode. For that reason I am considering find the best way for cashing data. I't like use SharedPreference for store data but in android documentation writen Maximum size in characters allowed for a preferences value is 8192. I don't know this is ok or not? I tried to pass out of this idea trying to use FileCashing or sqLite cashing.

So what you think guys what is the best SharedPreference vs FileCashing or vs SqLiteCaching?

Byroad answered 29/8, 2013 at 8:55 Comment(4)
SharedPreferences for the config data, and SQLite for mass data.Liborio
This is impossible to answer without knowing more details about your use case. Even then, it is a matter of opinion to some degree.Horoscopy
Let's say I have some data (i.e city list) I want my application store this json for later use if internet connection not available.Byroad
@Byroad i have to develop same kind of program, what approach you have used (sqlite or file caching) and can you share your github demo code link ...Signe
S
13

I personally like to do this the following way. Create a SQLite database that can hold your content. Then, bind the user interface directly to the database using Adapters & Content Providers that send a notification whenever the data is changed so that the UI can update itself. The last piece in the equation is some form of synchronization service that downloads content and saves it to the database asynchronously. That way, you can manage your data very easily because it is all in the same place. The only part you'll have to figure out for your app is how you decide when to update or remove the data from the database.

Adapters

ContentProvider

Synchronization

Sd answered 29/8, 2013 at 9:3 Comment(3)
I am keep thinking about Adapters & Content Providers how could I send notification?Byroad
A ContentProvider should call context.getContentResolver().notifyChange(<Your URI>, null); when the data has been changed. The activity in question would then use a ContentObserver to be notified of these changes.Sd
this depends on the sensitivity of the stored data. Mind you storing on sqite db or shared preference can be problematic, one only needs a rooted phone to access your whole dbGirand
B
20

Save the json in cache directory as file....

Save:

// Instantiate a JSON object from the request response
JSONObject jsonObject = new JSONObject(json);
// Save the JSONOvject
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(getCacheDir(),"")+"cacheFile.srl"));
out.writeObject( jsonObject );
out.close();

Retrieve:

// Load in an object
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(new File(getCacheDir(),"")+"cacheFile.srl")));
JSONObject jsonObject = (JSONObject) in.readObject();
in.close();
Blasto answered 29/8, 2013 at 9:34 Comment(3)
@Cristiana214 Same way but than remove the jsonobject instantation and just write the string to cache. And when retrieving just retrieve a String and not a JsonObject.Keto
Why did you create the File class twice when retrieving?Chattanooga
what if JSONObject was JSONArray, retrieved from an Array Json, how should I deal with it?Attack
S
13

I personally like to do this the following way. Create a SQLite database that can hold your content. Then, bind the user interface directly to the database using Adapters & Content Providers that send a notification whenever the data is changed so that the UI can update itself. The last piece in the equation is some form of synchronization service that downloads content and saves it to the database asynchronously. That way, you can manage your data very easily because it is all in the same place. The only part you'll have to figure out for your app is how you decide when to update or remove the data from the database.

Adapters

ContentProvider

Synchronization

Sd answered 29/8, 2013 at 9:3 Comment(3)
I am keep thinking about Adapters & Content Providers how could I send notification?Byroad
A ContentProvider should call context.getContentResolver().notifyChange(<Your URI>, null); when the data has been changed. The activity in question would then use a ContentObserver to be notified of these changes.Sd
this depends on the sensitivity of the stored data. Mind you storing on sqite db or shared preference can be problematic, one only needs a rooted phone to access your whole dbGirand
E
0

Based on your requirement I would recommend SQLite data base.

Since shared preference is suitable for configuration storage - often small data/strings.

File cache is hard to manage, so I recommend SQLite - easy to manage and ability to store mass data.

Considering the performance, if the number of index is not that huge, SQLite database should have the acceptable performance. E.g. only several ms slower than a file cache.

You might be able to combine these two approaches together. Use random access file with index-offset stored in SQLite.

European answered 29/8, 2013 at 9:3 Comment(1)
'only several ms slower than a file cache' yes, but remember that you'll not need json parsing then, it's parsed only one time.Clever
S
0

I have used Internal Storage which store file in Application package directory that can't be accessible by not rooted device.

Here the class which can create, read and delete the file

public class ReadWriteJsonFileUtils {
    Activity activity;
    Context context;

    public ReadWriteJsonFileUtils(Context context) {
        this.context = context;
    }

    public void createJsonFileData(String filename, String mJsonResponse) {
        try {
            File checkFile = new File(context.getApplicationInfo().dataDir + "/new_directory_name/");
            if (!checkFile.exists()) {
                checkFile.mkdir();
            }
            FileWriter file = new FileWriter(checkFile.getAbsolutePath() + "/" + filename);
            file.write(mJsonResponse);
            file.flush();
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String readJsonFileData(String filename) {
        try {
            File f = new File(context.getApplicationInfo().dataDir + "/new_directory_name/" + filename);
            if (!f.exists()) {
                onNoResult();
                return null;
            }
            FileInputStream is = new FileInputStream(f);
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            return new String(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        onNoResult();
        return null;
    }

    public void deleteFile() {
        File f = new File(context.getApplicationInfo().dataDir + "/new_directory_name/");
        File[] files = f.listFiles();
        for (File fInDir : files) {
            fInDir.delete();
        }
    }

    public void deleteFile(String fileName) {
        File f = new File(context.getApplicationInfo().dataDir + "/new_directory_name/" + fileName);
        if (f.exists()) {
            f.delete();
        }
    }
}

You can create, read and delete the file by calling ReadWriteJsonFileUtils class methods as follows:

For creating file:

try {
    new ReadWriteJsonFileUtils(context).createJsonFileData(file_name, data);
} catch (Exception e) {
    e.printStackTrace();
}

For reading file:

String jsonString = new ReadWriteJsonFileUtils(context).readJsonFileData(file_name);

For deleting single file

new ReadWriteJsonFileUtils(context).deleteFile(file_name);

For deleting all file

new ReadWriteJsonFileUtils(context).deleteFile();
Stillborn answered 19/3, 2016 at 20:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.