Question

So, I'm trying to figure out the best way to combine many data types together. Internal to my code, I'm creating a class. Externally, I want to have a single place to go to manage to following types of data, or at least pointers to said data. Note that there is a lot of sets of these data, and I anticipate adding more as time continues.

EDIT: I'm massively simplifying what was once here.

Imaging that at compile time, I have a list of objects. Each object has some characteristic, which all objects will have in common. These include:

  • An imageImage
  • Some strings
  • An array of Integers
  • An array of strings

I am wanting to find a way to store all of these together outside of any code. Ideally, I would like to use XML, with something that vaguely looks like this:

<storage_type>
   <image resid="@id/image1" />
   <name>Item_Name1</name>
</storage_type>
<storage_type>
   <image resid="@id/image2" />
   <name>Item_Name2</name>
</storage_type>

The images are currently stored as resource variables. I'm just not sure how I could put a reference to an image into the XML file.

I am not married to the idea of XML files, if a better solution can be found. All I want is a single database of some kind a way to access this information.

This data should not be changed, unless I submit a new update. These do not need to be updated at runtime, but I definitely would like to update them between builds, from time to time.. I've heard of Preferences, which might work, but I'm unsure if they might be user updatable somehow.

Was it helpful?

Solution

I was able to figure out a solution, with considerable help from this question.

  1. My data is stored in an XML array.
  2. This data contains an array index which points to an image array, maintained under a normal resource.

My data storage file looks like:

<storage_type>
   <image imageArrayIndex="1" />
   <name>Item_Name1</name>
</storage_type>
<storage_type>
   <image imageArrayIndex="2" />
   <name>Item_Name2</name>
</storage_type>

I have a file in my res/values folder that looks like:

<resources>
    <string-array name="images">
        <item>@drawable/default</item>
        <item>@drawable/image1</item>
        <item>@drawable/image2</item>
    </string-array>
</resources>

And somewhere deep in parsing XML code I have:

TypedArray imgs = context.getResources().obtainTypedArray(R.array.achievement_images);
//Whole bunch of code to parse XML, eventually coming to this line:
else if (name.equals("image"))
{
  imageRes=imgs.getResourceId(xpp.getAttributeIntValue(null,"imageArrayIndex", 0),-1);
}

Alternatively, I could simply store the name of the image like below:

<storage_type>
   <image resid="image1" />
   <name>Item_Name1</name>
</storage_type>
<storage_type>
   <image resid="image2" />
   <name>Item_Name2</name>
</storage_type>

And then get it by parsing the XML tag, and getting the resource ID by:

int resid=Context.getResources().getIdentifier (name_string_Image, "drawable", null);

OTHER TIPS

SharedPreferences is an option, but in that case later on even if you just need to change the values, you'll have to make changes in your code. The xml way on the other hand is more flexible.

In the future, if you just want to change the values for the settings, change the xml file and push it to your users' phones. No need to change the code, go through testing cycles, etc. And in case you want to add/remove stuff, then either ways would require change in code (specially the adding part)

The overhead for the xml ofcourse, would be the reader/writer part.

I think you could make a custom object that stores these values and has a method to output it to a JSON string (for storing in Prefs) and reconstruct by taking in the JSON string. You can also have methods that return the image of the object. Here is an example class I wrote:

public class MyObject {
    private static final String IMAGE_RES_ID = "ImageResId";
    private static final String STRING1 = "String1";
    private static final String STRING2 = "String2";
    private static final String INT_ARRAY = "IntArray";
    private static final String STRING_ARRAY = "StringArray";

    private int mImageResId;
    private String mString1, mString2;
    private int[] mIntArray;
    private String[] mStringArray;

    public MyObject(int imageResId, String s1, String s2, int[] intArray,
            String[] stringArray) {
        mImageResId = imageResId;
        mString1 = s1;
        mString2 = s2;
        mIntArray = intArray;
        mStringArray = stringArray;
    }

    public MyObject(String jsonString) throws JSONException {
        JSONObject jsonObject = new JSONObject(jsonString);

        // Get single values
        mImageResId = jsonObject.getInt(IMAGE_RES_ID);
        mString1 = jsonObject.getString(STRING1);
        mString2 = jsonObject.getString(STRING2);

        // Get arrays
        JSONArray intArray = jsonObject.getJSONArray(INT_ARRAY);
        mIntArray = new int[intArray.length()];
        for (int i = 0; i < mIntArray.length; i++)
            mIntArray[i] = intArray.getInt(i);

        JSONArray stringArray = jsonObject.getJSONArray(STRING_ARRAY);
        mStringArray = new String[stringArray.length()];
        for (int i = 0; i < mStringArray.length; i++)
            mStringArray[i] = stringArray.getString(i);
    }

    public int getImageResId() {
        return mImageResId;
    }

    public String getString1() {
        return mString1;
    }

    public String getString2() {
        return mString2;
    }

    public int[] getIntArray() {
        return mIntArray;
    }

    public String[] getStringArray() {
        return mStringArray;
    }

    public Drawable getImageDrawable(Context context) {
        return context.getResources().getDrawable(getImageResId());
    }

    private JSONObject toJsonObject() throws JSONException{
        JSONObject toReturn = new JSONObject();

        // Put single values
        toReturn.put(IMAGE_RES_ID, getImageResId());
        toReturn.put(STRING1, getString1());
        toReturn.put(STRING2, getString2());

        // Put arrays
        JSONArray intArray = new JSONArray();
        for (int value : mIntArray)
            intArray.put(value);

        JSONArray stringArray = new JSONArray();
        for (String value : mStringArray)
            stringArray.put(value);

        toReturn.put(INT_ARRAY, intArray);
        toReturn.put(STRING_ARRAY, stringArray);

        return toReturn;
    }

    public String toJsonString() throws JSONException {
        return toJsonObject().toString();
    }
}

Construct this once you have all the relevant information you want saved. Then store the result of toJsonString() in SharedPreferences and restore at run-time when needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top