I have a OnSharedPreferenceChangeListener
in a fragment that monitors two preferences. If either one of those change, it calls an AsyncTask. The details are not entirely necessary, but all the AsyncTask is doing is parsing an XML file and returning and int.
The code works fine, but I've noticed a minor issue that I would like to fix if I can.
If I go into preferences and change one of the two that "tied" to the listener, there is a slight delay after I click "Ok" in the preference dialog. From the logs, I can deduce that it is calling the AsyncTask before I actually get back to the Fragment (ie it is calling the AsyncTask in the Settings Fragment, which is in a whole separate Activity).
I assume this has something to do with the listener, but I am not quite sure.
Any suggestions?
Below is the code that is causing the issue:
SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(LOGCAT_TAG, "(ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: " + key);
if(key.equals(Reference.KEY_PREF_PLAYER_NAME) || key.equals(Reference.KEY_PREF_UNI)) {
//Load up the new prefs
String newPlayerName = sharedPreferences.getString(Reference.KEY_PREF_PLAYER_NAME, "");
String newUni = sharedPreferences.getString(Reference.KEY_PREF_UNI, "");
//Get the new iD
int tempInt = getUserIDFromAsyncTask(context, newPlayerName, newUni);
//If we still did not get an ID
if (tempInt == 0) {
Log.d(LOGCAT_TAG, "(ON SHARED PREFERENCE CHANGE LISTENER) A setting was changed. Attempted to get new ID to no avail.");
mTitleTextView.setText("Sorry. I couldn't find your new user ID.");
}
//We got a new ID
else {
Log.d(LOGCAT_TAG, "(ON SHARED PREFERENCE CHANGE LISTENER) New ID: " + tempInt);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(Reference.KEY_PREF_USER_ID, tempInt);
editor.commit();
}
}
}
};
//Register the listener
//TODO: Change/Move this because it may become garbage collected
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
You can tell that this is the code that is causing the issue by view the logs:
It appears that the listener is called 3 times, even though I only changed the setting once (Open settings, click settings, entered in new text, clicked okay)
07-17 13:14:19.162 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_name
07-17 13:14:20.063 18232-18241/com.example.game D/AbsListView﹕ [unregisterDoubleTapMotionListener]
07-17 13:14:20.063 18232-18879/com.example.game D/dalvikvm﹕ GC_FOR_ALLOC freed 1735K, 28% free 19420K/26952K, paused 28ms, total 29ms
07-17 13:14:20.063 18232-18241/com.example.game I/MotionRecognitionManager﹕ .unregisterListener : / listener count = 0->0,
07-17 13:14:20.063 18232-18241/com.example.game D/AbsListView﹕ unregisterIRListener() is called
07-17 13:14:20.133 18232-18879/com.example.game I/ParsePlayers﹕ Found matching ID @ line: 974
07-17 13:14:20.143 18232-18232/com.example.game I/HomeFragment﹕ ID From AsyncTask: 112696
07-17 13:14:20.143 18232-18232/com.example.game I/HomeFragment﹕ Adding ID to SharedPreferences!
07-17 13:14:20.163 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_id
07-17 13:14:20.163 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_id
07-17 13:14:20.163 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_id
07-17 13:14:20.163 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) New ID: 112696
07-17 13:14:20.163 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_name
07-17 13:14:20.544 18232-24361/com.example.game I/ParsePlayers﹕ Found matching ID @ line: 974
07-17 13:14:20.544 18232-18232/com.example.game I/HomeFragment﹕ ID From AsyncTask: 112696
07-17 13:14:20.544 18232-18232/com.example.game I/HomeFragment﹕ Adding ID to SharedPreferences!
07-17 13:14:20.544 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) New ID: 112696
07-17 13:14:20.544 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) Setting changed: game_player_name
07-17 13:14:20.944 18232-24219/com.example.game D/dalvikvm﹕ GC_FOR_ALLOC freed 2503K, 30% free 18964K/26952K, paused 26ms, total 26ms
07-17 13:14:21.034 18232-24219/com.example.game I/ParsePlayers﹕ Found matching ID @ line: 974
07-17 13:14:21.044 18232-18232/com.example.game I/HomeFragment﹕ ID From AsyncTask: 112696
07-17 13:14:21.044 18232-18232/com.example.game I/HomeFragment﹕ Adding ID to SharedPreferences!
07-17 13:14:21.044 18232-18232/com.example.game D/HomeFragment﹕ (ON SHARED PREFERENCE CHANGE LISTENER) New ID: 112696
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getExtractedText on inactive InputConnection
07-17 13:14:21.044 18232-18232/com.example.game I/HomeFragment﹕ Got this ID back: 112696
07-17 13:14:21.044 18232-18232/com.example.game I/HomeFragment﹕ Got this ID back: 112696
07-17 13:14:21.044 18232-18232/com.example.game I/HomeFragment﹕ Got this ID back: 112696
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getTextBeforeCursor on inactive InputConnection
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getTextAfterCursor on inactive InputConnection
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getSelectedText on inactive InputConnection
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getTextBeforeCursor on inactive InputConnection
07-17 13:14:21.044 18232-18232/com.example.game W/IInputConnectionWrapper﹕ getTextBeforeCursor on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ beginBatchEdit on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ finishComposingText on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ endBatchEdit on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ beginBatchEdit on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ finishComposingText on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ endBatchEdit on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ beginBatchEdit on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ finishComposingText on inactive InputConnection
07-17 13:14:21.054 18232-18232/com.example.game W/IInputConnectionWrapper﹕ endBatchEdit on inactive InputConnection
07-17 13:14:21.064 18232-18232/com.example.game W/IInputConnectionWrapper﹕ beginBatchEdit on inactive InputConnection
07-17 13:14:21.064 18232-18232/com.example.game W/IInputConnectionWrapper﹕ finishComposingText on inactive InputConnection
07-17 13:14:21.064 18232-18232/com.example.game W/IInputConnectionWrapper﹕ endBatchEdit on inactive InputConnection
07-17 13:14:21.064 18232-18232/com.example.game W/IInputConnectionWrapper﹕ beginBatchEdit on inactive InputConnection
07-17 13:14:21.074 18232-18232/com.example.game W/IInputConnectionWrapper﹕ finishComposingText on inactive InputConnection
07-17 13:14:21.074 18232-18232/com.example.game W/IInputConnectionWrapper﹕ endBatchEdit on inactive InputConnection
07-17 13:14:21.104 18232-18232/com.example.game D/AbsListView﹕ unregisterIRListener() is called
Following line of code is blocking the UI thread:
int tempInt = getUserIDFromAsyncTask(context, newPlayerName, newUni);
You are waiting for the result of an asynchronous task.
AsyncTask is intended for short tasks which may take a few seconds, but for which you don't want to lock up the UI thread. If you actually need a Future, your task is probably too complex for an AsyncTask anyway.
Solution:
You can start the AsyncTask
at onSharedPreferenceChanged
and handle the result in your AsyncTask.onPostResult()
. Not at the end of onSharedPreferenceChanged
.
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.