[Logo]
Forums Register Login
ArrayList Size Comes Back 0
I have a ListView connected to an Activity by a custom Adapter. In the Adapter, I collect the names of all non-system applications and display them in the list. Each list item also includes a Switch. When a list item's switch is clicked, I have the relevant package name being written to an ArrayList<String> in the Activity.

This is the relevant part of the Adapter code where that is occurring:



Then in my Activity, on a button click, I send the ArrayList<String> as an extra with an Intent to another Activity that triggers an Intent as startActivityForResult(). Here is the relevant code for that:

Here's where the Intent starts...


This is where the ArrayList<String> is being passed back to the parent Activity...


On the receiving end of the Intent, I grab the extra and then attempt to set a TextView to display the number of items in the ArrayList<String>. However, when I test the app in the emulator, the TextView displays 0...

Here is the code for the triggering Activity, where I get the extras and set the TextView:


I have also attached an image from the emulator demonstrating that the TextView is coming back as 0. For the life of me, I cannot figure out why it isn't working right.
Screen-Shot-2018-01-19-at-7.18.50-PM.png
[Screen-Shot-2018-01-19-at-7.18.50-PM.png]
(Forgive me if this is bad forum manners) ::Bump::

I still haven't been able to figure out what is happening here.
Could you create an SSCCE for us? Something we can easily run on an emulator without all the code and data that is not relevant to the problem?
Try doing some debugging by adding print statements to show the values of different variables being used.
What is in the Intent: data?

Note: I'd use a more unique id as request code than 1 to identify the Intent.
You were right to bump the thread after a week. Anything significantly more than a day could justify a bump.

I can't seem to see where you are adding anything to the List.

Last week, you wrote:Each list item also includes a Switch.

That isn't clear. Do you mean that each item added to the List includes a Switch?
@Campbell Ritchie - Yes, there is a switch in each list item. I have not included the full source code, so no, you do not see where I am adding items to the list. However, there are things being added from PackageManager.

@Norm Radder - I am using Toasts to help with debugging. When a switch in the ListView is clicked, a Toast prints the relevant String being added to my ArrayList. Then another toast prints the ArrayList's new size after the item has been added. Insofar as I can see, the ArrayList is properly populating. It seems that there is something happening with the Intent. After clicking on 'Save' in the Activity where the Intent extras originate, I have a Toast in onActivityResult() that looks like this:



That Toast shows the itemCount as being 0. However, I have a conditional that only shows the Toast if selectedStuff isn't empty. AND, I can go into the connected database and see that variableOne, variableTwo, and variableThree are appropriately coming through. However, in the field for selectedStuff it simply shows []. PS--I had changed my code to 11 since my OP.

@Stephen van Hulst - Due to the nature of the project I am working on, there is a lot in terms of limitation. I cannot share all of the code, and the code I do share has to be made generified. It's a lot of extra leg work on my part.
The problem with using Toasts is that the output can't be copied from the logcat and pasted it here so we can see what is happening.

Another possible problem is the use of literal Strings in the put and get methods.  There should be one final String defined that is used in  both places to make sure the same value is used in both places.
Same for the request code: it should be a final int, not hardcode literals in different places in the code.
 

Norm Radder wrote:The problem with using Toasts is that the output can't be copied from the logcat and pasted it here so we can see what is happening.

Another possible problem is the use of literal Strings in the put and get methods.  There should be one final String defined that is used in  both places to make sure the same value is used in both places.
Same for the request code: it should be a final int, not hardcode literals in different places in the code.




Using final Strings is probably a better "best practice" option but it is not the problem for me. I have checked and re-checked both put and get statements and they are identical. Furthermore, as I have said, my other extras are working just fine. It is only the selectedStuff ArrayList that is giving me problems.
Seeing these bits and pieces of code that don't go together makes it hard to suggest what the problem is.
These have different id Strings:
A few items if I may.

Point 1:
Instead if using Toast, you logcat as Norm has already suggested. Android Studio (and possibly other Android development environments) make this easy to do.
You can do this with as noted here https://developer.android.com/studio/debug/am-logcat.html and here https://developer.android.com/reference/android/util/Log.html.
Within Android Studio, there is even a short cut for this, just type logd then press the tab key.

Point 2:
There is an limit to the amount of data that can be sent using the putExtraXXX methods as noted here https://www.neotechsoftware.com/blog/android-intent-size-limit.
It is therefore recommended that you put small objects when using putExtraXXX methods.
Instead of placing an array/arraylist in a bundle and sharing that, create a temporary file or database entry and place the path to that in the bundle.
Do you know the approx size of the array/arrayList?

Point 3:
I think that Norm mentioned this, but it can be hard to keep track of numbers like . It is usually easier to do something like this:

Doing something like that you can not only share the codes if you need to, but you can quickly change the values without do that many find and replaces.
 

Norm Radder wrote:Seeing these bits and pieces of code that don't go together makes it hard to suggest what the problem is.
These have different id Strings:




ūüė© They are actually one and the same. As I had said before, I have to generify the code when I share it. It looks like I forgot to generify a line or two.
Different names etc  makes the code very hard to understand.
Did you add lots of print statements to record the states as the code executes to show what is happening?

Please copy the print out and paste it here.
 

Pete Letkeman wrote:A few items if I may.

Point 1:
Instead if using Toast, you logcat as Norm has already suggested. Android Studio (and possibly other Android development environments) make this easy to do.
You can do this with as noted here https://developer.android.com/studio/debug/am-logcat.html and here https://developer.android.com/reference/android/util/Log.html.
Within Android Studio, there is even a short cut for this, just type logd then press the tab key.

Point 2:
There is an limit to the amount of data that can be sent using the putExtraXXX methods as noted here https://www.neotechsoftware.com/blog/android-intent-size-limit.
It is therefore recommended that you put small objects when using putExtraXXX methods.
Instead of placing an array/arraylist in a bundle and sharing that, create a temporary file or database entry and place the path to that in the bundle.
Do you know the approx size of the array/arrayList?

Point 3:
I think that Norm mentioned this, but it can be hard to keep track of numbers like . It is usually easier to do something like this:

Doing something like that you can not only share the codes if you need to, but you can quickly change the values without do that many find and replaces.







Thank you for taking the time type that all out!

Regarding point #1: Your code wouldn't work in Android Studio as is. It should be...


Regarding point #2: The array I am testing with is very small and contains only one short String in it. So, size is not the issue here. However, it might create an issue in future, so I thank you for the references.

Regarding point #3: I do acknowledge that using a final string is probably a better practice. However, not using such practices is not at the root of my problem. I have verified as much multiple, multiple times.
Sorry I forgot that you must used String.valueOf when dealing with the Android logger.

What if, simply for testing you did
Instead of If this change gives you the data you are expecting then you have a problem somewhere else with how selectedApps is being used/created.

Over here https://stackoverflow.com/questions/6543811/intent-putextra-list they mention that one option could be to use getSerializable. However they also say that what you have should work.
 

Pete Letkeman wrote:Sorry I forgot that you must used String.valueOf when dealing with the Android logger.

What if, simply for testing you did
Instead of If this change gives you the data you are expecting then you have a problem somewhere else with how selectedApps is being used/created.

Over here https://stackoverflow.com/questions/6543811/intent-putextra-list they mention that one option could be to use getSerializable. However they also say that what you have should work.



I did as you've suggested but to no avail. Here's where things currently are:

In my adapter class, I am adding/removing items to/from the Array list...



The log reflects that the item(s) are successfully added:



Then I create and send the Intent when the save button is clicked, as such (the ... is a placeholder for redacted code):



At this point, the log changes:




Subsequently, one can easily guess what the log will reflect on the get side of things:





This is all quite bizarre.
As you were...

I was copying/pasting code but forgot to update certain things.

The first log is:


The second log is:


The third log is:
The message text's should be unique so you can tell which statement generated which output.
These look all the same.
 

Norm Radder wrote:The message text's should be unique so you can tell which statement generated which output.
These look all the same.





I know the placement of the log lines in relation to how my code is being executed, as I communicated clearly in my previous post where
I actually lay out the various steps.

The first log is written right after a switch is clicked on the list. The second log is written just prior to the put statement for my ArrayList.
Finally, the third log is written just after the get statement is executed.
It is clearer if all the log contents are unique so everyone can see which statement generated which output.
Though it is nothing more than a "best practice," I went ahead and made the logs unique.



That said, nothing has changed with regards to the functionality of my application.
It is evident that something is happening to the ArrayList between the time the switch is clicked and when it is being added to the Intent. Hmmmm....
 

nothing more than a "best practice,"


No, I think it is more than that. It  is one of the ways to find bugs in code.

How can the value go from 1 at Switch to 0 at put?  Is a new ArrayList created?  Is there a Log statement for when the ArrayList is created?
 

How can the value go from 1 at Switch to 0 at put?  Is a new ArrayList created?  Is there a Log statement for when the ArrayList is created?



I stripped everything out, in terms of the ArrayList and am re-working it step-by-step. Here is what I have so far:

At the top of my adapter class, I initialize a new ArrayList...


Then, in the onClick method for my switch, I add or remove strings to/from the ArrayList accordingly...



Now, I must put the ArrayList with the Intent I trigger in the Activity to which the Adapter connects. That's where I seem to be running into problems.
So, I attempted to clone the ArrayList in the Adapter (which the Switch adds to) to an ArrayList in the Activity:



I am still getting:

 

I am still getting:

V/Array Size - Before put: 0


Is that all that is printed by the Log statements?

Why are you filtering out any of the print outs?
Does this ever get printed: Array Size - Switch off

The debug print outs should have a full history of the state of the ArrayList:
When it is created
when any change is made to it: adds and removes
When its contents are accessed
I have a bit of a digression I want to explore before we continue on this track.

Is there a way for me to get an instance of the switch in my Adapter, in my Activity? My thought is that if I can setup the onClickListener in the Activity, I can cut a lot of the "middleman" stuff out, thus fixing my problem.

I created an instance of my Adapter's ViewHolder in my Activity:



Then I set up an onClickListener for the switch in my Activity's onCreate method:



However, I am getting a NullPointerException. What am I missing?
Please start a new thread for the new problem.
I would be curious to know what is the result of the following line if placed right before the for loop?
With a value of 0 for the ArrayList selectedApps I would suspect that the reported size of applicationsAdapter to be 0 as well.
 

Pete Letkeman wrote:I would be curious to know what is the result of the following line if placed right before the for loop?
With a value of 0 for the ArrayList selectedApps I would suspect that the reported size of applicationsAdapter to be 0 as well.



Yes, it come s back 0 too.
In that case I am suspect that there is something not exactly correct with applicationsAdapter.getSelectedApps().
Effectively the for loop which you have as
is actually
 

Pete Letkeman wrote:In that case I am suspect that there is something not exactly correct with applicationsAdapter.getSelectedApps().
Effectively the for loop which you have as
is actually



The Strings are added in the Adapter class, where I presently have the Switch's onClickListener. I suspect there is something happening to the data between the Adapter and the Activity it's attached to (where I add the ArrayList to an Intent).
That's why I am now exploring moving the onClickListener over to the Activity from the Adapter. I just don't know how to properly get an instance of the Switch with which to do that. I am getting a NullPointerException on the switch. I've started a new thread to try to tackle that issue.
 

Norm Radder wrote:

I am still getting:

V/Array Size - Before put: 0


Is that all that is printed by the Log statements?

Why are you filtering out any of the print outs?
Does this ever get printed: Array Size - Switch off

The debug print outs should have a full history of the state of the ArrayList:
When it is created
when any change is made to it: adds and removes
When its contents are accessed





This is (redacted) verbose from the Logcat:



It doesn't appear to include anything of great importance, in addition to the logs I've already shared.
What other accesses to the ArrayList happen before line 11 and between line 11 and line 17?
 

Norm Radder wrote:What other accesses to the ArrayList happen before line 11 and between line 11 and line 17?



Before 11:



Between 11 & 17:

When is the statement that prints this: V/Array Size - Switch on: 1 executed?
 

Norm Radder wrote:When is the statement that prints this: V/Array Size - Switch on: 1 executed?



That occurs in the ViewHolder for the Adapter class:

(0 likes, 1 cow)
Ok, I'm giving up.  This is too frustrating. Trying to get the order of events is too hard without seeing the code.  The print outs don't show enough information.

Maybe someone with more patience can help.
Adam, can we start at the beginning? Maybe I can sum up what is happen here, please correct me if I'm wrong.
1) You suspected that there was a problem with an ArrayList loosing it's data.
2) Recently we discovered that the actual problem was not with the ArrayList, but the Adapter feeding the ArrayList.
3) You are using a ListView?
4) You are working on creating some sort of Launcher for Android

What kind of adapter are you using? It could be a RecycleViewAdapter, but it could be a different adapter such as an ArrayAdapter or some other kind?
Here is a sample/tutorial on the ArrayAdapter http://abhiandroid.com/ui/arrayadapter-tutorial-example.html.

I would recommend that you use the RecycleView which does support at least Android 4.4 (KitKat).
Eveything that a ListView  can do a RecycleView can do.
RecycleView also has features that are not found in ListView like the built in Holder class/pattern.

Currently you are trying to implement an onClick event in the holder which you have attached to the adapter. Is this correct?

Is all of what I've stated above in this post correct?

------------ Unpaid Book Promo ------------
I can tell you from experience that in the book Android Programming: The Big Nerd Ranch Guide (3rd Edition) found here
https://www.bignerdranch.com/books/android-programming/ which you can see on Amazon.com here
https://www.amazon.com/Android-Programming-Ranch-Guide-Guides/dp/0134706056/
They walk though a tutorial in one of the chapters giving you the code create your own custom Android launcher.
Not only that they provide you with a primer on using SQLite, Fragments, Activities and more.
You could get the PDF version of this book and be on you way very quickly with not only the project that you are currently working on, but other projects.
-----------------------------------------------
 

Pete Letkeman wrote:Adam, can we start at the beginning? Maybe I can sum up what is happen here, please correct me if I'm wrong.
1) You suspected that there was a problem with an ArrayList loosing it's data.
2) Recently we discovered that the actual problem was not with the ArrayList, but the Adapter feeding the ArrayList.
3) You are using a ListView?
4) You are working on creating some sort of Launcher for Android

What kind of adapter are you using? It could be a RecycleViewAdapter, but it could be a different adapter such as an ArrayAdapter or some other kind?
Here is a sample/tutorial on the ArrayAdapter http://abhiandroid.com/ui/arrayadapter-tutorial-example.html.

I would recommend that you use the RecycleView which does support at least Android 4.4 (KitKat).
Eveything that a ListView  can do a RecycleView can do.
RecycleView also has features that are not found in ListView like the built in Holder class/pattern.

Currently you are trying to implement an onClick event in the holder which you have attached to the adapter. Is this correct?

Is all of what I've stated above in this post correct?

------------ Unpaid Book Promo ------------
I can tell you from experience that in the book Android Programming: The Big Nerd Ranch Guide (3rd Edition) found here
https://www.bignerdranch.com/books/android-programming/ which you can see on Amazon.com here
https://www.amazon.com/Android-Programming-Ranch-Guide-Guides/dp/0134706056/
They walk though a tutorial in one of the chapters giving you the code create your own custom Android launcher.
Not only that they provide you with a primer on using SQLite, Fragments, Activities and more.
You could get the PDF version of this book and be on you way very quickly with not only the project that you are currently working on, but other projects.
-----------------------------------------------




Although I have suspicions as to what is happening, it is only speculation because I cannot collect enough debug info.

That said, let me summarize what is happening and, in the process, hopefully answer your prior questions.
For the record, after reading your previous post, I did decide to change my ListView to a RecyclerView. Between the time I
read your response and now, I have been working on writing a new adapter class and implementing it. So, now I have a
RecyclerView in my Activity that uses a custom RecyclerView Adapter. In my override of onBindViewHolder in the Adapter,
I have a Switch view. When the Switch isChecked, it adds a String, which is packageInfo.PackageName, to an ArrayList
that lives in the Activity. When the switch is clicked, I write the size of the ArrayList in the Activity to the log, as such:



Then, in the Activity I create an Intent to which I attach some Extras, including the ArrayList. At that point, I have
another log entry being made, which is the size of the ArrayList right prior to the putExtra statement for the Intent (... denotes redacted code):



Then, in the Activity prior to this, the one waiting for this Activity's result, I use a standard conditional with get statements.
There are 4 Extras altogether, 3 Booleans and 1 StringArray. These values are later written to a database.

Now, the problem...I can click the aforementioned and see in the log that the ArrayList in the Activity has a size of 1...
or however many switches have been clicked. However, my next log entry comes back 0:



Implementation:

In the Activity using the Adapter, I initialize a new ArrayLise just before the onCreate method:


Then, in the Adapter, just before the Constructor, I grab an instance of the Activity:


Then, in the ViewHolder for the adapter, I grab the Switch:


Then, in the onBindViewHolder method within my Adapter, I set a new onClickListener for the Switch.
In the onClick method, I add a conditional that adds the String to the ArrayList in the Activity if the Switch isChecked:
I finally took the time to create an SSCCE (Gradle build in Android Studio)...


Download a zip archive of the project. (It is about 20 MB)
Wink, wink, nudge, nudge, say no more ... https://richsoil.com/cards


This thread has been viewed 5707 times.

All times above are in ranch (not your local) time.
The current ranch time is
Feb 24, 2018 09:23:04.