tray icon indicating copy to clipboard operation
tray copied to clipboard

changeVersion doesn't support multithreading. -> NullPointerException

Open toy-lin opened this issue 7 years ago • 4 comments

Very thanks for your product,but i have got a NullPointerException while migrating data,can anybody give me some advice?

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference at net.grandcentrix.tray.core.SharedPreferencesImport.onPostMigrate(SharedPreferencesImport.java:79) at net.grandcentrix.tray.core.SharedPreferencesImport.onPostMigrate(SharedPreferencesImport.java:38) at net.grandcentrix.tray.core.Preferences.migrate(Preferences.java:125) at ...module.sp.CookiePreferences.importSP(CookiePreferences.java:47) at ...module.sp.CookiePreferences.onCreate(CookiePreferences.java:29) at net.grandcentrix.tray.core.Preferences.changeVersion(Preferences.java:262) at net.grandcentrix.tray.core.Preferences.isVersionChangeChecked(Preferences.java:292) at net.grandcentrix.tray.core.Preferences.(Preferences.java:58) at net.grandcentrix.tray.core.AbstractTrayPreference.(AbstractTrayPreference.java:31) at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:43) at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:48) at ..*.module.sp.CookiePreferences.(CookiePreferences.java:23)

And below is code in CookiePreferences:

`public class CookiePreferences extends TrayPreferences { private static final String TAG = CookiePreferences.class.getSimpleName(); public static final String MODULE = "cookie"; private static final String SP_NAME = "mycookie"; public CookiePreferences(Context context) { super(context, MODULE, 1); }

@Override
protected void onCreate(int initialVersion) {
    super.onCreate(initialVersion);
    importSP();
}

private void importSP() {
    final SharedPreferences sps = getContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
    HashMap<String, Object> all = new HashMap<>(sps.getAll());

    Set<Map.Entry<String, Object>> set = all.entrySet();
    for (Map.Entry<String, Object> en : set) {
        String key = en.getKey();
        SharedPreferencesImport ip = new SharedPreferencesImport(getContext(), SP_NAME, key, key);
        migrate(ip);
    }
}

}`

Version:

compile 'net.grandcentrix.tray:tray:0.11.1'

toy-lin avatar Apr 21 '17 03:04 toy-lin

Oh, i have found the problem.I thought Tray is thread safe but it's not. In my case ,method 'onCreate' was invoked twice from different thread. Am i wrong with my code?

toy-lin avatar Apr 24 '17 03:04 toy-lin

Yes,Tray isn't thread safe.The lock to check version change is a TrayPreferences object, so if we create more than one TrayPreferences object in different thread , method 'onCreate' would probably be invoked more than 1 time. "synchronized void changeVersion(final int newVersion)"

toy-lin avatar Apr 25 '17 09:04 toy-lin

Good finding. We will fix that

passsy avatar Apr 25 '17 10:04 passsy

The same problem would happen in onCreate if multiple process start at the same time

bdelville avatar Jun 18 '19 05:06 bdelville