简体   繁体   中英

App update deletes old shared prefs data from internal storage

In my app, I have a database of objects that are generated by the user and then saved to the internal storage using shared prefs when the user leaves the app. Now when the user re-opens the app, that data is retrieved and presented to the user for further editing. I noticed that when I roll out an update to my app and the user installs it, all the data is lost. I tried retrieving it by saving the app's current version code using shared prefs and then comparing it to the current one in order to know when it's an app update and then i call the Read & Write data methods to retrieve the old data but with no luck. Any ideas on how i should approach this issue?

SerializeGLB.java:

public class SerializeGLBData {

/**
 * Writes the Global User Box's cardList to the user's internal storage using the Gson
 * library so that the user doesn't lose his/her data.
 * @param cardList The list to write to the internal storage
 * @param context Getting the app's current context
 */
public static void Write(ArrayList<Card> cardList, Context context) {

    SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = appPrefs.edit();
    Gson gson = new Gson();
    String cardsGLBJson = gson.toJson(cardList);
    editor.putString("cardsGLB",cardsGLBJson);
    editor.apply();
    editor.commit();
    Log.d("WriteData","Data written successfully!");
}

/**
 * Reads the cards list that gets saved when the app closes
 * @param context Get the app's current context
 * @return Returns an ArrayList of Card Objects containing the card info
 */
public static ArrayList<Card> ReadCards(Context context) {
    SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    Gson gson = new Gson();
    String cardsGLBJson = appPrefs.getString("cardsGLB","");
    Type type = new TypeToken<ArrayList<Card>>(){}.getType();
    return gson.fromJson(cardsGLBJson,type);
}

}

 private void checkForFirstRun() {

    final String PREF_VERSION_CODE_KEY = "version_code";
    final int DOESNT_EXIST = -1;

    // Get current version code
    int currentVersionCode = BuildConfig.VERSION_CODE;

    // Get saved version code
    SharedPreferences prefs = getSharedPreferences(PREFS_NAME,MODE_PRIVATE);
    int savedVersionCode = prefs.getInt(PREF_VERSION_CODE_KEY, DOESNT_EXIST);

    // Check for first run or upgrade
    if(currentVersionCode == savedVersionCode) {
        // This is just a normal run
        Log.d("RUN_TYPE:" , "Normal Run");
    } else if(savedVersionCode == DOESNT_EXIST) { // This is a new install(or the user cleared the shared prefs)
        CallWriteDataMethods(this);
        Log.d("RUN_TYPE:", "New Install");
        // Showing the tutorial page when the app starts for the first time
        Intent tutorialIntent = new Intent(this, Tutorial.class);
        startActivity(tutorialIntent);
        UsernameDialog dialog = new UsernameDialog();
        dialog.setCancelable(false);
        dialog.show(getFragmentManager(),"USERNAME_DIALOG");
    } else if(currentVersionCode > savedVersionCode) { // This is an upgrade
        CallWriteDataMethods(this);
        Log.d("RUN_TYPE:","Update");
    }

    // Update the shared prefs with the current version code
    prefs.edit().putInt(PREF_VERSION_CODE_KEY,currentVersionCode).apply();
    return;
}

 public static void CallWriteDataMethods(Context context) {
    // Write all the -empty- data from GlobalDataHolder to the internal memory to avoid a first time read error
    SerializeGLBData.Write(GlobalDataHolder.cards,context);
    // Write all the -empty- data from JPDataHolder to the internal memory to avoid a first time read error
    SerializeJPData.Write(JPDataHolder.cards,context);
}

 /**
 * Calls every available Read method to retrieve all available data from the GLB database
 */
public static void callReadDataMethodsGLB(Context context) {
    GlobalDataHolder.cards = SerializeGLBData.ReadCards(context);
    Log.i("Read Methods[GLB]", "ReadMethods called!");
}

/**
 * Calls every available Read method to retrieve all available data from the JP database
 */
public static void callReadDataMethodsJP(Context context) {
    JPDataHolder.cards = SerializeJPData.ReadCards(context);
    Log.i("Read Methods[JP]", "ReadMethods called!");
}

How does your SerializeGLBData.Write function works? Because by reading your code, when you are in the case of an upgrade, you are only calling the CallWriteDataMethods directly, and according to your comment in it:

// Write all the -empty- data from GlobalDataHolder to the internal memory to avoid a first time read error

You are writing the memory with empty data. Are your writing functions checking if data exists before putting empty data in it?

So something like

if(!prefs.contains("your_data_key")) {
   // your code to add data
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM