Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-16968] Android: App crashes due to ListView modifications

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2014-05-21T19:25:39.000+0000
Affected Version/sn/a
Fix Version/s2014 Sprint 10, 2014 Sprint 10 SDK, Release 3.3.0, Release 3.4.0
ComponentsAndroid
Labelsandroid, crash, listview, module_kitchensink, qe-testadded, triage
ReporterMark Mokryn
AssigneeHieu Pham
Created2014-05-05T06:48:22.000+0000
Updated2014-07-29T23:55:01.000+0000

Description

On occasion I am seeing app crashes with the log below. Unfortunately, I have not been able to reproduce this in a simple test case, but it does happen on occasion in my app, during certain sequences. The issue is clearly stated in the error log: the ListView has been modified outside the UI thread. Reviewing the ListView code, there are several places where such issues can occur. In ListSectionProxy.java, for example the following methods *definitely* modify the ListView without first making sure the UI thread is running: setHeaderView, setFooterView, setHeaderTitle, and setFooterTitle. And indeed - *the issues in my code went away* after I stopped calling setHeaderTitle. Note that these methods ensure the UI thread is running only to call adapter.notifyDataSetChanged(), but the changes themselves may clearly be made outside the UI thread - which is a bug. Additionally - I'm not sure that setting the ListView.sections property is UI thread safe. I strongly suggest Appcelerator reviews ListView code to ensure it is all UI thread safe. {color:red} 05-04 19:03:15.566: E/AndroidRuntime(9698): FATAL EXCEPTION: main 05-04 19:03:15.566: E/AndroidRuntime(9698): 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(-1, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)] 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.ListView.layoutChildren(ListView.java:1510) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.AbsListView.onLayout(AbsListView.java:1260) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 05-04 19:03:15.566: E/AndroidRuntime(9698): at ti.modules.titanium.ui.widget.listview.TiListView$ListViewWrapper.onLayout(TiListView.java:139) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at org.appcelerator.titanium.view.TiCompositeLayout.onLayout(TiCompositeLayout.java:580) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1589) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at org.appcelerator.titanium.view.TiCompositeLayout.onLayout(TiCompositeLayout.java:580) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.onLayout(LinearLayout.java:1047) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.LinearLayout.onLayout(LinearLayout.java:1047) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.View.layout(View.java:7175) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.ViewRoot.performTraversals(ViewRoot.java:1140) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.os.Handler.dispatchMessage(Handler.java:99) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.os.Looper.loop(Looper.java:130) 05-04 19:03:15.566: E/AndroidRuntime(9698): at android.app.ActivityThread.main(ActivityThread.java:3683) 05-04 19:03:15.566: E/AndroidRuntime(9698): at java.lang.reflect.Method.invokeNative(Native Method) 05-04 19:03:15.566: E/AndroidRuntime(9698): at java.lang.reflect.Method.invoke(Method.java:507) 05-04 19:03:15.566: E/AndroidRuntime(9698): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 05-04 19:03:15.566: E/AndroidRuntime(9698): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 05-04 19:03:15.566: E/AndroidRuntime(9698): at dalvik.system.NativeStart.main(Native Method) {color}

Comments

  1. Mark Mokryn 2014-05-05

    See pull request: https://github.com/appcelerator/titanium_mobile/pull/5658 My issues have been fixed for now by this PR, but I still urge Appcelerator to review all the ListView code to make sure there are no further manifestations of this bug. Specifically - is the creation dictionary being handled in the UI thread? See explanation of why this PR is required: https://github.com/mokesmokes/titanium_mobile/commit/1b88f411ef87449343a51af6d301dc629290f26b
  2. Mark Mokryn 2014-05-15

    No comment from Appcelerator on an issue that causes app crashes???
  3. Ingo Muschenetz 2014-05-15

    Mark, we have a number of tickets coming in from different sources as we wind down 3.3.0 and I was not alerted to this one yet. I've placed it into triage. Thank you for following up.
  4. Mark Mokryn 2014-05-15

    That's fine. Just a quick overview to help you guys with this one: all I did was modify the 4 offending ListSection methods that were not written in the usual pattern of running methods on the UI thread - very straight forward and the review should be simple. Unfortunately as this is a threading/timing issue the crash is not easy to replicate - even debug prints can move the timing one way or another, also device dependent, etc - but it definitely was happening on occasion and this fixed it.
  5. Hieu Pham 2014-05-21

    3.3.X PR: https://github.com/appcelerator/titanium_mobile/pull/5720
  6. Lokesh Choudhary 2014-06-17

    [~hpham] - can you please provide any test steps/code to verify the fix for this ticket.
  7. Hieu Pham 2014-06-18

    Testing steps: Run KS -> views -> list views -> headers and footers, make sure everything is working as expected.
  8. Lokesh Choudhary 2014-06-19

    Verified the fix by running test in KS -> views -> list views -> headers and footers & did not find any issues. Closing. Environment: Appc Studio : 3.3.0.201406171619 Ti SDK : 3.3.0.v20140617161713 Mac OSX : 10.8.5 Alloy : 1.4.0-rc CLI - 3.3.0-rc Code Processor: 1.1.1 Samsung Galaxy S4 - android 4.2.2

JSON Source