简体   繁体   中英

Registering/Unregistering OnSharedPreferenceChangeListener

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 .

AsyncTask

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