Office Hours — Today, January 14

Thursday, January 9

Jan 14
3:50 PM
Mark M.
has entered the room
Mark M.
turned on guest access
3:55 PM
EGHDK
has entered the room
EGHDK
Hey Mark, so two big "problems" I'm having. Both have to do with listViews.
Mark M.
hello, EGHDK!
go ahead
EGHDK
My first problem is basically, I need to have a menu show up in a list view. It's simple. breakfast, dinner, and lunch. Every Monday the menu is the same, every tuesday the menu is the same... etc
breakfast lunch and THEN dinner. lol
So, I basically put these set menu's in a database.
4:00 PM
EGHDK
7 insert statements (one for each day of the week), and then each entry has three columns. breakfast, lunch, dinner.
That is basically the first half of it. Pretty simple, and I think I'm doing it efficiently. (in regards to using a database, and not another data structure).
The only other thing is that sometimes, the menu can change last second, so I have a web based interface settup to override a certain menu.
That works too. I pull out the values for breakfast, lunch and dinner and store them in arrays (because they were split with commas) and then make a network call and if anything is updated, I update the proper array.
So now, it's time to display this in a listView.
Ernie
has entered the room
EGHDK
I want three Headers (B, L, D) and have each array show up below the proper header. But I'm not sure how to do that.
Ernie
has left the room
EGHDK
I created this SO question to try and get some direction. http://stackoverflow.com/questions/21109440/con...
4:05 PM
Mark M.
you got five answers
EGHDK
So I'm even more confused then when I started.
Mark M.
admittedly, the answers are mostly poor
EGHDK
Yeah, it wasn't the high grade answers I usually get.
Mark M.
the simplest answer is to use my MergeAdapter
Step #1: Create three ArrayAdapters, one for each array, set up to render those rows however you want
Step #2: Create three views for the headers, however you want those to look
Step #3: Pour them all into the MergeAdapter, using addView() (for a header), then addAdapter() (for the array to appear below the header), for each of your three header/adapter pairs
Step #4: Put the MergeAdapter into the ListView
Step #5: Beer
EGHDK
I like step 5.
Heh. Thanks very clear and concise. I was going nuts, because I didn't know how I can use three different arrays as my data
So you don't think there is anything wrong with how I architectured the activity?
Mark M.
the AmazingListView and the StickyListHeaders from the 5th answer are also reasonable choices, though I haven't used them
I wouldn't have set things up quite the same way that you did, but, then again, I do not completely understand the problem domain, and therefore may be missing some bits
4:10 PM
EGHDK
True.
My goal was basically to make sure that the list fills up with data. and then I do the network call.
if the network call returns anything, then I need to update one of my arrays.
Mark M.
I would think the right answer is to have the right data before presenting it to the user
EGHDK
Do you think that will cause me any trouble?
Mark M.
it will make things more complicated to code and more confusing to the user
I'd throw up a ProgressBar, do the network I/O, then populate the ListView with the final result
EGHDK
Yeah, but since the user is just me, I will be feeling it out how it works this way. I know its not the best way, since technically the menu could change right before their eyes.
But that's the purpose of this demo app.
Mark M.
if it's just you, I'd use a Post-It Note(R) and skip the app... :-)
EGHDK
hahaha
Well, knowing all of that information, and that "that" is the desired outcome of the app. How do you recommend I update lets just say the breakfast array?
4:15 PM
Mark M.
use add(), insert(), and remove() on the ArrayAdapter
EGHDK
got it.
Okay, so onto my second question!
So I want to build a blogRoll application. I've already created an application that takes the last ten posts from a JSON api from a wordpress site, and displays it in a list.
So this works fine... I have two problems with it. I'm unsure of how to create something that when I scroll down, it does another call for the next 10 posts. and my second problem is, that I need this to be stored persistantly. so that lets say I'm looking at it, and I go into a tunnel or elevator, I can still go through the posts. How would I go about creating something like that? A database should work...?
4:20 PM
Mark M.
with regards to the second part, that's up to you
a database is a likely candidate
with regards to the first part, there are various solutions floating around, like my EndlessAdapter: https://github.com/commonsguy/cwac-endless
EGHDK
Well now I'm just thinking. Should I download the data, and insert it directly into the DB, then query the DB and display that?
Mark M.
well, I cannot really answer that
personally, I would not persist it
or, I would be going with a synchronization strategy, not a "when the user pulls up the app, then do the network I/O"
not the approach that you're going with
there's nothing technically wrong with your approach, but it's not how I would look at the problem
EGHDK
Yeah, that was my original plan. But I don't know how to go about it.
Mark M.
which "that" and "it" are you referring to?
EGHDK
Not going with "open the app, network call"
I don't know how to go about a synchonozation strategy
Mark M.
first, write the activity to work against a persistent store, rather than doing the network I/O itself
again, the choice of store is up to you, and I don't know enough about a blogroll data structure to make a suggestion
EGHDK
"work against a persistent store"?
Mark M.
"work against a persistent store" = "query a database" OR "read a file" OR "whatevs"
4:25 PM
EGHDK
Gothca. Just making sure I was on the same page.
Mark M.
then, you need to decide when you want to update that persistent store from the network, in addition to perhaps offering a manual "check now, please" option from the activity
for example, maybe you want to update the database every 24 hours
for that, you could use AlarmManager, triggering a service to do the network I/O and update the database
the "check now, please" would also kick off the service to do the same thing, just on demand
if the service detects changes (e.g., it inserted new rows), the UI needs to know about that, if the UI happens to be in the foreground
your choices there are either to use an event bus (LocalBroadcastManager, Otto, greenrobot's EventBus, etc.) or to use a ContentProvider and a CursorLoader as the way you access the database (so it will deliver you a fresh Cursor when data changes)
I cover event buses and thet ContentProvider/CursorLoader options in the book
EGHDK
Well, the blog roll really consists of 4 things. Title, Author, Content, and Image so it's mostly text, but I think I might just store the text in the Database and not store the image
4:30 PM
Mark M.
bear in mind that if you do not download the image (e.g., to getCacheDir()), you will be unable to show it in the elevator scenario
you can display a placeholder instead, if you prefer
EGHDK
How does toGetCacheDir work?
Mark M.
getCacheDir() returns a File object, pointing to a space on internal storage where you can store files
it works just like getFilesDir(), except that the contents of getCacheDir() can be deleted if needed to free up disk space
EGHDK
Let's say I get the json api of 1 blog post, I get the title, I get the author, I get the title, and I get the link to the picture. I would download the picture toGetCacheDir, and save the location of the cached image in the database?
Mark M.
yes
EGHDK
I'm gettin good at this!
Awesome.
4:35 PM
EGHDK
So since I have you here... I was working on another app that uses this https://code.google.com/p/aacdecoder-android/. It starts to stream music via a link I give it in an async task. It works fine... when I'm in the activity/app. After that it behaves weird. I thought after I leave the activity that starts an asyncTask. The asynctask stops. So I plan on starting it in a service, but I'm confused to how the asyncTask still plays music even when I back out of the activity.
Mark M.
why wouldn't it?
AsyncTask is not tied to an activity lifecycle
unless you do something to stop the task, the task will keep rolling
until the task completes
EGHDK
Whaaat. I'm so confused. I was asking around, and someone said, whatever creates a thread, if the thing that creates it dies, then so does the thread.
Mark M.
well, that depends on the scope and definition of "thing"
if "thing" = "process", your statement is correct
if "thing" = "activity", your statement is incorrect
4:40 PM
EGHDK
Interesting. I was going off of this question I posted a while ago. http://stackoverflow.com/questions/17954383/ser...
"A Thread should be destroyed when the Thread that started it is destroyed. So, if you start a Thread in an Activity then it should be destroyed when that Activity is destroyed or transferred to a Service. For instance, you can start music in a Thread and update the songs there but if you want it to keep playing when the Activity is destroyed then it should be moved to a Service"
Mark M.
in the first quoted sentence, the implication is that *you* should destroy the thread, not that the thread *automatically* is destroyed
at a quick glance, William Morrison's answer is better
EGHDK
So let's say I have activity A and B. I go from A to B, and in B I start a hugeeeee insert/query in an async. Before the async is done... I press the back button to go back to Activity A. If I touch the GUI in postExecute will I get an error because I'm not there anymore?
Mark M.
BTW, for these SO questions, you are welcome to use the new "bump" feature of your Warescription
EGHDK
Oh yeah, I saw that today when I logged on. Will definitely give all of your features a try.
Mark M.
does "touch the GUI" mean "call a method on the activity that started the AsyncTask"?
4:45 PM
EGHDK
Either that, or I try to update the listView that was on Activity B.
Mark M.
that probably would involve calling a method on that activity
regardless
you usually will not get an error
even though Activity B is destroyed, the objects still exist
they will attempt to do the work
but then there will be no visual result, because the activity is destroyed
there may be some things that might cause an exception, but I cannot think of any examples
EGHDK
Oh. So even though B is destroyed, AsyncTask may be holding onto some of the objects.
Mark M.
AsyncTask holds onto whatever it can reach
so, if the AsyncTask can "update the listView that was on Activity B", by definition, the instance of Activity B is still reachable
and, hence, is not garbage collected
EGHDK
So when asynctask completes, then everything in activity B will be dead. (unless static variables or something)
Mark M.
everything in Activity B will be (hopefully) unreachable and therefore will be eligible for garbage collection
when the garbage collection routines get around to it
EGHDK
Gotcha.
So if I create a huge insert statement in activity B, and then I press the home button. I can assume that it is still going to try to complete the huge insert statement?
Mark M.
yes
EGHDK
Beautiful. Didn't know that.
4:50 PM
Mark M.
the risk is that Android may terminate the process before the work gets done
EGHDK
Okay, so the last thing is, I "risk" the insert statement not completing.
Oh. I was right!
So, if I NEED this insert statement to go through, I can create a service, to make sure it doesn't get killed with the application?
Mark M.
it greatly increases the odds of success
there are no guarantees in life
I'd use an IntentService, as it gives you the background thread that you also need
but I'd also do some performance testing
if you feel confident that the work will get done in less than a second, your AsyncTask is probably fine
as nothing else is likely to clobber your process quite that quickly
EGHDK
True. I will keep that in mind. I started to dive into services using the Marakana Android bootcamp, but he totally lost me. He said that there are two types of services or something.
Mark M.
well, depending on how you score it, there are lots of types of services
we as developers typically focus on the plain Service and the IntentService
EGHDK
And one service is used for inside apps, and another one is used for outside apps.
Mark M.
ah, he was referring to whether or not a service is exported, and is available as a remote service
EGHDK
Yeah. If I want to keep my music playing, would I export my service?
4:55 PM
Mark M.
only if you are expecting some third-party app to control your service
otherwise, no
EGHDK
Okay. The only thing I want to control my service is my notification.
When I start playing music, I want a notification to show up with a stop button.
In that case... I still don't have to export... correct?
Mark M.
note that "a stop button" is only available on the expanded notifications available starting with 4.1 or so
correct, you will not need to export the service
EGHDK
yeah
Awesome.
Okay, thanks a lot as always.
Mark M.
you are very welcome
EGHDK
I always recomend your book everywhere I go! People ask me how I got so good at android. Always point them to your direction.
Mark M.
many thanks!
EGHDK
I also tell them that I should actually read the book more and not rely on stack overflow, but... I always have so many little questions.
Have a good night mark. Again appreciate it!
Mark M.
if you need it, the next chat is Thursday, 7:30pm US Eastern Time
and the chat transcript should be uploaded to http://commonsware.com/office-hours/ shortly
5:00 PM
Mark M.
have a pleasant day!
EGHDK
has left the room
Mark M.
turned off guest access

Thursday, January 9

 

Office Hours

People in this transcript

  • EGHDK
  • Ernie
  • Mark Murphy