OnSharedPreferenceChangeListener注册/取消注册



我在一个片段中有一个OnSharedPreferenceChangeListener,它监视两个首选项。如果其中任何一个改变,它调用AsyncTask。细节并不是完全必要的,但是AsyncTask所做的只是解析XML文件并返回int。

代码工作正常,但我注意到一个小问题,我想修复如果我可以。

如果我进入首选项并更改与侦听器"绑定"的两个中的一个,在我单击首选项对话框中的"确定"后会有轻微的延迟。从日志中,我可以推断出,它是调用AsyncTask之前,我实际上回到片段(即它是调用设置片段的AsyncTask,这是在一个完整的单独的活动)。

我认为这与听众有关,但我不太确定。

有什么建议吗?

下面是导致这个问题的代码:
    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);

您可以通过查看日志来判断这是导致问题的代码:

似乎侦听器被调用了3次,即使我只更改了一次设置(打开设置,点击设置,输入新文本,点击确定)

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

下面一行代码阻塞了UI线程:

int tempInt = getUserIDFromAsyncTask(context, newPlayerName, newUni);

您正在等待异步任务的结果。

AsyncTask用于可能需要几秒钟的短任务,但您不想锁定UI线程。如果你真的需要一个Future,你的任务对于AsyncTask来说可能太复杂了。

解决方案:

您可以在onSharedPreferenceChanged处启动AsyncTask,并在AsyncTask.onPostResult()中处理结果。不是在onSharedPreferenceChanged结尾

AsyncTask