Адаптер курсора пользовательского списка падает при bindView на эмуляторе, а не на телефоне - PullRequest
2 голосов
/ 23 августа 2010

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

Настоящая загадка для меня заключается в том, что мое приложение падает на моем эмуляторе, но при установке на моем телефоне (через загрузку apk на телефон, а затем с помощью приложения AppInstaller с маркета) оно работает.

Сбой происходит из-за исключения NullPointerException в пронумерованной строке в следующем фрагменте кода (мой код) настраиваемого адаптера курсора списка.

// TaskListCursorAdapter.java

@Override
public void bindView(View view, Context context, Cursor cursor) {

    super.bindView(view, context, cursor); // <<< LINE 36
    // DO OTHER BINDING OF STRINGS TO TEXT VIEWS ETC

Создан следующий дамп ошибки.

08-23 21:58:57.251: ERROR/AndroidRuntime(346): Uncaught handler: thread main exiting due to uncaught exception
08-23 21:58:57.411: ERROR/AndroidRuntime(346): java.lang.NullPointerException
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:149)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at adriaansapps.com.tasks.TaskListCursorAdapter.bindView(TaskListCursorAdapter.java:36)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at adriaansapps.com.tasks.TaskListCursorAdapter.newView(TaskListCursorAdapter.java:83)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.CursorAdapter.getView(CursorAdapter.java:182)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.AbsListView.obtainView(AbsListView.java:1274)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1147)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.ListView.onMeasure(ListView.java:1060)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:888)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:619)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:280)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:569)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:361)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:464)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.View.measure(View.java:7964)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.ViewRoot.performTraversals(ViewRoot.java:763)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.os.Looper.loop(Looper.java:123)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at android.app.ActivityThread.main(ActivityThread.java:4363)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at java.lang.reflect.Method.invokeNative(Native Method)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at java.lang.reflect.Method.invoke(Method.java:521)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at dalvik.system.NativeStart.main(Native Method)

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

Я подозреваю, что это может быть проблема с базами данных, но на самом деле не уверен - там нет ничего неуместного. До сегодняшнего дня у меня была база данных только с одной таблицей - сегодня я добавил новую таблицу, в которой также есть поле «_id» в качестве поля ключа автоинкремента имени, которое, как я прочитал в документации, было необходимо для адаптеров списка Android (если память служит) , Имея некоторый опыт в кодировании и небольшой опыт работы с базами данных, это кажется мне плохой идеей, но я не уверен, является ли это проблемой и / или как еще это сделать.

Сбой, который я перечисляю здесь, не отображает и не ссылается на данные в другой новой таблице. Курсор не содержит никаких данных запроса. Фактически, если я переименую поле ключа «_id» новой таблицы во что-то другое (например, «_blah»), аварийное завершение останется.

Как я уже сказал, если я загружаю apk на свой телефон, он работает.

Я пробовал на эмуляторе следующее: - перезапуск АБР (и затмение) - безрезультатно - удалить из эмулятора - нет результата - профиль AVD Destory и воссоздать - без результата

Я занимаюсь разработкой этого пакета под Android 2.1 SDK и работаю последние несколько недель. У меня только что был установлен этот SDK, я еще не обновился до 2.2.

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

Без исправления я могу ожидать очень медленный процесс разработки здесь (при условии, что мне нужно загрузить на свой телефон, чтобы проверить новые изменения кода ...).

Извините за то, что долго думал - надеюсь, я предоставляю достаточно информации для одного из вас, умных людей, чтобы понять это. Спасибо

Ответы [ 4 ]

1 голос
/ 12 декабря 2010

Ваша проблема в том, что вы не переопределяете методы getViewTypeCount и getViewType. Если вы не переопределите эти методы, иногда Android будет вызывать ваш getView с параметром "convertView" неправильного типа, если вы передадите этот параметр в getView адаптера, вы получите исключение NullPointerException при попытке повторного использования объекта. *

Почему это работает в телефоне? Я не уверен, может быть, версия SimpleCursorAdapter в телефоне проверяет, что передаваемый вами параметр "convertView" имеет правильный тип. Я обнаружил случай сбоя эмулятора 2.1, но не 1.5, 1.6, 2.2 или моего телефона.

Если вы хотите попробовать более простой способ решения проблемы (но менее оптимальный), вы всегда можете передать параметр "convertView" в SimpleCursorAdapter как "ноль". Таким образом, SimpleCursorAdapter никогда не будет повторно использовать любой вид, но он работает в любом месте (эмулятор всех версий + телефон).

Вы можете проверить это руководство Джеффом Шарки

Разделение списков с заголовками в Android 0,9

1 голос
/ 23 августа 2010

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

08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at adriaansapps.com.tasks.TaskListCursorAdapter.bindView(TaskListCursorAdapter.java:36)
08-23 21:58:57.411: ERROR/AndroidRuntime(346):     at adriaansapps.com.tasks.TaskListCursorAdapter.newView(TaskListCursorAdapter.java:83)

Просто установите адаптер ListView / GridView с ListView.setAdapter (...) и позвольте магии случиться.

0 голосов
/ 23 августа 2010

Глядя на исходный код Android 2.2, я вижу, что SimpleCursorAdapter bindView() может поднять NullPointerException только в том случае, если массив to, который вы предоставили конструктору, был null или если Cursor, которое вы указали в конструкторе, было null.

Теперь, безусловно, есть некоторые изменения в SimpleCursorAdapter между 2.1 и 2.2, так как строка 149 редакции 2.2 отсутствует в bindView().Следовательно, может быть какой-то другой возможный случай для NullPointerException в 2.1, который я не вижу в 2.2.

0 голосов
/ 23 августа 2010

Посмотрите чуть выше журналы logcat.Вы можете обнаружить, что есть ошибка SQL (обычно желтым цветом), и это может что-то сказать о неоднозначном имени столбца.Возможно, вам потребуется добавить имя таблицы, за которым следует точка, чтобы получить столбец _id.

У меня была эта проблема вчера из-за этой проблемы.

Почему это может не произойти на вашем телефонепотому что у вас может не быть новой таблицы, созданной должным образом на телефоне.Попробуйте очистить данные (используя приложение управления приложениями) и снова запустить ваше приложение.

Я на 95% уверен, что ваша проблема заключается в неоднозначных именах столбцов, и вы найдете их в logcat чуть выше, чемошибка, которую вы опубликовали, возможно, на 3 строки выше.

...