Stackoverflow только для Android 2.3.3
Я работал над Native Android App
, где я сталкиваюсь с некоторой ошибкой на purticularly Android 2.3.3 versions and below Android 3.0 version
.
Я не получаю, где именно попадает в мой код, потому что в Logcat каждая строка кода скомпилирована, но в конце появляется очень странная ошибка, описывая журнал ниже:
java.lang.StackOverflowError
at java.util.concurrent.locks.ReentrantLock$NonfairSync.tryAcquire(ReentrantLock.java:189)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1171)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
at java.util.concurrent.CopyOnWriteArrayList.removeRange(CopyOnWriteArrayList.java:569)
at java.util.concurrent.CopyOnWriteArrayList.remove(CopyOnWriteArrayList.java:366)
at java.util.concurrent.CopyOnWriteArrayList.remove(CopyOnWriteArrayList.java:376)
at android.view.ViewTreeObserver.removeOnPreDrawListener(ViewTreeObserver.java:377)
at android.widget.TextView.onDraw(TextView.java:4085)
at android.view.View.draw(View.java:6986)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:7093)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.widget.ScrollView.draw(ScrollView.java:1421)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.drawChild(ViewGroup.java:1737)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.View.draw(View.java:6989)
at android.widget.FrameLayout.draw(FrameLayout.java:361)
at android.view.ViewGroup.drawChild(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1466)
at android.view.ViewGroup.d
Как я проверил свой код, я не нашел трассировки для stackoverflow. Когда я запускаю тот же код на Android версии 3.0 или выше, он работает эффективно и корректно, но не на версии Android 2.3.3 и ниже 3.0.
Пожалуйста, дайте мне знать, знает ли кто-нибудь об этой проблеме?
[EDIT] Я использую вкладку Tab, поэтому основной макет Main.xml и в этом подзадаче хранит представление под названием firstTab_Results.xml, он содержит макет таблицы, который действительно выполняет раздувание макс. 20 просмотров inflate_table_firstTab.xml макета.
[EDIT 2] Я все равно не рекурсирую его, он раздувает Max 20 просмотров (inflate_table_firstTab.xml) в макет таблицы (firstTab_Results.xml).
Note : Stackoverflow happens on single or dual core processor devices & without fullscreen mode .
Ответы
Ответ 1
Ваша иерархия просмотров слишком глубока. Когда иерархия рисуется рекурсивно, вы исчерпываете пространство стека и не можете углубляться в иерархию, как это наблюдается в трассировке стека.
Почему это происходит только в более ранних устройствах, потому что размер стека потоков пользовательского интерфейса составляет всего 12 КБ на устройствах Android 2.3, но 16 КБ в более поздних версиях ОС (ref).
Как уменьшить глубину иерархии представления? Просто избегайте макетов вложенности, когда это возможно. Раскладки, которые вы размещаете, слишком сложны, и в вашей модели Qaru нет точки, фиксирующей их для вас (требуется некоторое время, чтобы сделать это правильно, и это, вероятно, слишком специфично, чтобы помочь другим), но вот несколько общих рекомендаций:
-
Удалите ненужные макеты. Например, в вашем файле firsttab_results.xml вам нужен только TableLayout
, RelativeLayout
и LinearLayout
сверху - это почти бесполезно. В вашем ScrollView
есть как минимум 6 вложенных макетов, когда одного или не более двух, вероятно, будет достаточно.
-
Один ребенок в макете - это запах кода. В большинстве случаев это может быть достигнуто, перемещая ребенка на родительский макет и корректируя макет с полями.
-
Обычно нет необходимости размещать макеты внутри RelativeLayout
. Относительная компоновка мощна при размещении своих детей с использованием относительного позиционирования и выравнивания базовой линии.
-
Если вам нужен вложенный макет только для background
, попробуйте переместить фон, например. просто View
, который имеет тот же размер, что и вложенный макет, и выкладывает другие элементы поверх него.
-
Обратите внимание на предупреждения Android Lint. Инструмент стал довольно хорошим в обнаружении сложностей иерархии представлений, которые могут быть упрощены.
Ответ 2
У вас есть вложенная иерархия представлений, в которой вы можете увидеть свою иерархию представлений с помощью hierarchyViewer в android. если у вас много вложенных представлений в вашем приложении, то некоторые устройства имеют небольшую память, которые предоставляют исключение, а для других он запускает well.flatten ваши взгляды. используйте RelativeLayout, чтобы сгладить представления.
Ответ 3
Я не думаю, что вы видите свою ошибку из-за "вложенности" ваших взглядов. Я думаю, что это может быть проблема с использованием того, что раньше устройства не имеют доступа в своей библиотеке, и ваш идеон не ловит его, либо у вас есть предупреждения на линт, и они игнорируют их. Попробуйте взглянуть на свои предупреждения на линт и посмотреть, не упоминает ли он что-либо о некоторых представлениях или api, которые недоступны в более ранних версиях.
Ответ 4
Стека на Android ограничена 8K, даже, по крайней мере, на Samsung Galaxy S3, которая имеет 2 ГБ оперативной памяти. Я не знаю, отличается ли он от устройства. Я не знаю, почему, я спросил, и они закрыли мой вопрос.
Ваш Main.xml очень вложен, любой используемый код, вероятно, вызывает переполнение стека. Количество стека, используемого для уровня вложенности, зависит от реализации, поэтому оно происходит с одной версией, а не с другой. Одна версия может вызывать цепочку из 5 функций, которая затем обрабатывает следующий уровень вложенного XML и т.д., И одна может быть цепочкой 20.
Ответ 5
Используете ли вы рекурсию для создания своей иерархии представлений? Я почти никогда не вижу StackOverflowError
без рекурсии.