Android - Контекстное меню - Исключение из-за того, что MenuBuilder $ MenuAdapter изменился без AlertController $ RecycleListView, получающего уведомление - PullRequest
3 голосов
/ 23 декабря 2010

Я искал все выше и ниже, чтобы найти ответ на вопрос, почему происходит сбой нашего приложения, когда пользователь нажимает на один пункт контекстного меню, а затем несколько раз нажимает на другой. Вот трассировка стека, которая у меня есть, и все это на внутренних классах Android:

11-11 15:08:30.904: ERROR/AndroidRuntime(3489): FATAL EXCEPTION: main
11-11 15:08:30.904: ERROR/AndroidRuntime(3489): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(16908808, class com.android.internal.app.AlertController$RecycleListView) with Adapter(class com.android.internal.view.menu.MenuBuilder$MenuAdapter)]
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.widget.ListView.layoutChildren(ListView.java:1550)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:2192)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.widget.ListView.onTouchEvent(ListView.java:3377)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.View.dispatchTouchEvent(View.java:3766)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1720)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1117)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.app.Dialog.dispatchTouchEvent(Dialog.java:642)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1704)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1794)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.os.Looper.loop(Looper.java:143)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at android.app.ActivityThread.main(ActivityThread.java:4701)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at java.lang.reflect.Method.invokeNative(Native Method)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at java.lang.reflect.Method.invoke(Method.java:521)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-11 15:08:30.904: ERROR/AndroidRuntime(3489):     at dalvik.system.NativeStart.main(Native Method)
11-11 15:08:30.912: WARN/ActivityManager(1261):   Force finishing activity com.pyxismobile.pyxWholesaler.ui.activity/.GNBActivity
11-11 15:08:30.943: WARN/WindowManager(1261): No window to dispatch pointer action 1
11-11 15:08:30.943: WARN/WindowManager(1261): No window to dispatch pointer action 0
11-11 15:08:30.943: WARN/WindowManager(1261): No window to dispatch pointer action 1

Базовый дизайн, который мы имеем, находится в классе Activity, который мы переопределяем onCreateContextMenu и onContextMenuItem. При создании код в основном заполняет коллекцию MyMenuItems, где у каждого элемента есть метод run для выполнения того, что нам нужно для выполнения пункта меню. OnContextMenuItem в основном берет идентификатор из переданного в MenuItem, ищет в коллекции заданный идентификатор, а затем просто запускает этот метод run.

Чтобы попытаться выяснить причину, я прокомментировал часть выполнения, чтобы ничего не делать. Это все еще вызывает исключение. Я не видел ничего особенного между созданием и нажатием, когда мы изменили бы какие-либо данные. Все сделано один раз в создании.

Я пытался создать очень простое тестовое приложение, однако я не смог получить это исключение. Я также кратко посмотрел на внутренний исходный код Android, чтобы узнать, смогу ли я что-нибудь выяснить, но ничего не вышло.

Если у кого-нибудь есть какие-либо предложения о том, что я могу делать неправильно, или о том, что на это посмотреть, будем благодарны.

Редактировать: Я также решил, что это не зависит от устройства. Мне удалось воссоздать на нескольких устройствах, однако в редких случаях это не происходит. Я предполагаю, что есть какое-то состояние гонки.

Ответы [ 2 ]

0 голосов
/ 23 апреля 2011

Старайтесь не менять адаптер после добавления его в ListView.

Если вам все еще нужно изменить содержимое ListView во время его использования, тогда установите видимость вашего ListView на GONE во время обновления адаптера и обратно на VISIBLE после обновления.

0 голосов
/ 21 апреля 2011

Настройте myMenuAdapter.registerDataSetObserver(DataSetObserver observer) ( API здесь ), чтобы регистрировать изменения и пытаться повторить ошибку на телефоне, подключенном к ПК с adb logcat. Это может дать вам подсказку, когда оно модифицируется.

Может ли быть так, что вы снова инициализируете адаптер вместо его повторного использования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...