是否总是在UI线程上调用onSharedPreferenceChanged

时间:2012-05-23 19:14:16

标签: android sharedpreferences

我有一个单例类来注册一个首选项更改侦听器,如:

PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext())
            .registerOnSharedPreferenceChangeListener(
                    preferencesChangeListener);

当更改某些首选项时,onSharedPreferenceChanged方法会通知感兴趣的组件有关事件的信息。其中一个感兴趣的组件更新了ListAdapter中的数据。我得到一些异常,表明这个列表适配器正被一个不是UI线程的线程修改。

我已经查看了更改适配器数据的代码路径,但没有看到任何错误。我唯一的疑问是,在UI线程中没有调用首选项更改侦听器中的onSharedPreferenceChanged

文档表明此方法为called on the UI thread

  

此回调将在您的主线程上运行。

有没有人见过不是这种情况?使用应用程序上下文注册我的首选项更改侦听器是否重要?

更新:这是堆栈跟踪。此异常时,数组大小始终为0。这就是为什么我要看一下共享首选项侦听器,因为这是我清除适配器中数据的唯一代码路径。索引不为零,因此它表示之前有数据。

> java.lang.IndexOutOfBoundsException: Invalid index 51, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
at java.util.ArrayList.get(ArrayList.java:311)
at com.palta.earthquake.EarthquakeAdapter.getItem(EarthquakeAdapter.java:56)
at com.palta.earthquake.EarthquakeAdapter.getView(EarthquakeAdapter.java:86)
at android.widget.AbsListView.obtainView(AbsListView.java:1294)
at android.widget.ListView.makeAndAddView(ListView.java:1727)
at android.widget.ListView.fillUp(ListView.java:682)
at android.widget.ListView.fillGap(ListView.java:628)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:2065)
at android.widget.ListView.onTouchEvent(ListView.java:3315)
at android.view.View.dispatchTouchEvent(View.java:3765)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:905)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:944)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:944)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:944)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:944)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:944)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1701)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1116)
at android.app.Activity.dispatchTouchEvent(Activity.java:2093)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1685)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1802)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4914)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

您是否在Android< = 2.2上运行该应用?如果是,commit()实现在2.3中更改,以便它始终在主线程中执行(因此也onSharedPreferenceChanged()),但不在2.2中。

请参阅this thread