My setup is as follows: inside my onCreate I initialize an ArrayList as follows:
textList = new ArrayList<HashMap<String, String>>();
// unrelated code ...
if (isConnected()) {
new DisplayTextTask().execute(sectionId);
}
and the AsyncTask fetches text via HttpURLConnection()
, parses the json using JsonReader
, and adds each line of text to the textList (all of this happens inside the AsyncTask's doInBackground
. I have a custom Adapter that displays the strings in textList
.
I also have a function gotoNextSection()
that gets triggered when the user wants to navigate to the next page, where I do something like:
gotoNextSection() {
if (isConnected()) {
new DisplayTextTask().execute(sectionId+1);
}
}
However, since I don't want the stale text from the previous page to remain on screen, I do the following in my AsyncTask:
private class DisplayTextTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
textList.clear();
}
@Override
protected String doInBackground(String... urls) {
// json parsing is called in getData()
try {
return getData(urls[0]);
} catch (IOException e) {
return "Could not load text";
}
}
so that the arrayList is empty and ready to be repopulated. All of this works fine in all other supported Android versions but when I tried it in a Marshmallow emulator gotoNextSection()
results in an IndexOutOfBoundsException. This occurs after the new content is added to the freshly cleared arrayList (verified via logging), so I don't think it's a race condition. Note that not clearing the list prevents the exception, and since this is the only ArrayList used in the Activity I'm positive that .clear()
is the problem. I've tried nulling and reinitializing it before launching the AsyncTask as an alternative as well, to no avail. Again, this happens exclusively on Android 6.0. Thoughts?
EDIT:
Here's the logcat stacktrace. Note that the size of index that it's attempting to access and where in the code this occurs is irrelevant because I've tried to log the ArrayList after the task is executed in gotoNextSection
and it just gives me an exception for whatever index I've tried to access in the log.
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at android.widget.HeaderViewListAdapter.isEnabled(HeaderViewListAdapter.java:164)
at android.widget.ListView.dispatchDraw(ListView.java:3329)
at android.view.View.draw(View.java:16181)
at android.widget.AbsListView.draw(AbsListView.java:4142)
at android.view.View.updateDisplayListIfDirty(View.java:15174)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
at android.view.View.updateDisplayListIfDirty(View.java:15134)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2615)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2434)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Solved: I ended up having to disconnect the adapter from the ListView before calling clear and reconnecting it afterwards in postExecute(), I'm guessing Marshmallow is more strict about data binding
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With