Office Hours — Today, July 27

Friday, July 17

Jul 27
8:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Refael O.
has entered the room
Mark M.
hello, Refael
how can I help you today?
Refael O.
hey there Mark !
I have a little problem with a project i'm working on right now, instead of writing the thing in here, could you take a look at the question I already opened in stack overflow and then we'll talk?
i added UI images there too
Mark M.
OK
got a link?
Refael O.
EGHDK
has entered the room
9:00 AM
Mark M.
(BTW, hi EGHDK, I will be with you shortly!)
Refael: well, I don't really know what to tell you, other than to start simplifying your problem to see what exactly is required in terms of contributions to your issue
Refael O.
well, i'll put it like that
I have a screen that I need to put 2 images the you can swipe left and right to toggle between them
Mark M.
I mean, you are using a third-party ListView, plus a ViewPager in a header view
Refael O.
yes i do
Mark M.
temporarily get rid of the third-party ListView stuff and see if your problem recurs with an ordinary ListView
ditto the "sticky view"
Refael O.
continue with EGHDK
Mark M.
um, OK
Refael O.
i'll be right back after trying it
=]
EGHDK
I have a note taking app that allows anyone to save a note. I'm trying ridiculous scenarios now with auto inserting thousands of notes. I want to list them in a listView, and with thousands of notes, I've decided that I only want to show a few hundred and "paginate" the rest. More like, show more only if the user gets to it. Does that make sense? My cursor would only be storing 200 entries instead of 200,000 entries, if I do it that way, plus I'm converting each cursor item into a pojo. So if I "paginate" I'm only loading 200 entry cursor and 200 objects.
Mark M.
EGHDK: your turn! do you have a question?
IMHO, pagination is a hack to support the wrong UI flow
nobody wants to scroll through thousands of entries
whether they are paginated or not
EGHDK
True. But just in case they do... does that sound right? (searching thousands of items is my next question... dont worry). hahaha
9:05 AM
Mark M.
um, I don't really see how what you propose is going to work in practice, as ListAdapter doesn't really support it
it's bad enough to try to do the "extend the data model with more data when the user reaches the bottom"
I did that with cwac-endless, which I deprecated because it (and the pattern) sucked
I have no idea how you're going to pull off an arbitrary window into an arbitrarily-large data set
EGHDK
Hmm... so you're saying that enlarging the data model is really what the issue is here?
Mark M.
I'm sure that there's some solution, but I can't tell you what it is
well, 200K entries is barrelling down the path towards an OutOfMemoryError
the theory of only holding 200 entries at a time is sound
EGHDK
I was thinking of loading just another 200 values. and discarding the other 200. Just in case extending the data model didn't work.
Mark M.
and when the user scrolls back up, then what?
EGHDK
And it gives the user the chance to scroll up if he/she really really really needs to.
Reload the other 200... =/
Mark M.
I am skeptical that you will get a good UX out of that flow
EGHDK
It's not an ideal solution, but IF the user REALLY wants to go back in time, then it's possible.
You bring up valid points about UX.
Mark M.
basically, either the ListAdapter is reporting 200K for getCount(), or something lower (e.g., 200)
EGHDK
So in a nutshell, the "hard" thing about pagination is that is hard to "extend the data model"?
Mark M.
it's hard to extend the data model at the right time and fast enough
EGHDK
Or that ListAdapter doesn't really support it?
Or is the ListAdapter the DataModel?
Mark M.
if your ListAdapter returns 200K for getCount(), it *can* support it, if you can get the data loaded fast enough at the right time
basically, your choice of window size (e.g., 200) needs to be "how much could the user get through in some rapid flings"
9:10 AM
Mark M.
so that by the time you run out of data, you have more data
if, OTOH, you wanted ListAdapter to return 200 from getCount(), then you'll definitely have some UX hiccups when the user reaches either end of the current content
EGHDK
Mark, I was going to try to search onScrollChanged, and when the user got to the halfway point of the list, I was going to load another 200.
Mark M.
and what happens if you can't load it fast enough?
EGHDK
Display a header at the top of the list that says "Loading"
Mark M.
ListView and ListAdapter can't handle that, insofar as you *have* to do *something* in getView() when it asks for a row for a position
you can't tell it "sorry, the data is still loading... please hold"
EGHDK
So how'd you end up doing cwac-endless (even though its depracated).
You had to have some sort of solution?
Mark M.
UX hiccups
user scrolls to the bottom, I kick off a task to get more data, with a "loading..." row
once the data is ready, replace the "loading" row with the next N rows loaded from the task
but it didn't handle reducing the data set size
as I did not have a good way of doing the reverse process for scrolling up
EGHDK
So you still had to load the original 200k?
Mark M.
well, eventually, if the user scrolled far enough, yes
EGHDK
Oh. But you were able to get it to work with loading pieces of the entire dataset right?
9:15 AM
Mark M.
so, in my case, getCount() returned the actual number of rows I had, plus 1 for the loading row
for some value of "get it to work", yes
like I said, it sucked
EGHDK
Okay, so when you hit loading now, what'd you do?
Load another new window and add it onto the previous Adapter?
Or did you have to replace the adapter?
Mark M.
it only worked with ArrayAdapter, so I kicked off an AsyncTask, where I told the app "yo, gimme more data" in doInBackground(), and appended the rows in onPostExecute(), including cleaning up the "loading" row
(BTW, Refael: let me know when you're ready to continue)
EGHDK
Okay, I'm using an array adapter... so this still may work. What's listadapter vs arrayadapter?
Mark M.
ListAdapter is an interface, extending the Adapter interface
Refael O.
Hey Mark, i'm ready to continue when you are done with EGHDK.
Mark M.
ArrayAdapter implements ListAdapter
CursorAdapter implements ListAdapter
etc.
EGHDK: let me take a question from Refael, and I will be back with you in a bit
Refael: go ahead!
EGHDK
Gotcha. Thanks Mark.
9:20 AM
Refael O.
Well, now i am using pure android code, no third library party
third party library*
you were right about one thing...
the width bug as seen in my images in stack overflow is now GONE...
so apparently that was caused by something in the QuickReturnListView library
but my 2nd bug still happens..
images in the view pager not always load up
Mark M.
what are you using for pages in your ViewPager? fragments or views?
Refael O.
View paste
i am loading the images with a third party library also..
but.. that's like the best way to load images with cache and stuff..

in my pager i have a pager adapter that holds 2 fragments
Mark M.
OK, when are you telling the image-loading library to load the images?
Refael O.
in my onResume method of that activity
i am sending a Server request to get the data
i get images inside a JSONObject and the images url I am giving to Ion library
9:25 AM
Mark M.
well, double-check to confirm that you are actually loading the images that are missing, and consider using setCallback() to find out when Ion is done loading the images (https://github.com/koush/ion#futures)
or possibly try Ion's logging to see whether it is loading the images (https://github.com/koush/ion#logging)
let me turn back to EGHDK for a bit, and I'll return to you soonish
EGHDK: back to you! do you have another question?
9:30 AM
Refael O.
View paste
hmmm okie.. that will require some time to log and check that, and I am currently on a tight schedule for a different feature of that project.
i'll check that later on today and get back to you for the office hours of tomorrow!

thanks a lot Mark, as always.. you are a saver.
EGHDK
How would I paginate or implement this infinite scroll in the list view? Is onScrollChangedListener sufficient enough?
Or do I wait untnil the "Loading more" getView is called?
Mark M.
EGHDK: as I said, I gave up on this pattern a while ago
I was skeptical about the scroll-changed listener, due to timing
again: what happens if you wait too long, as you don't have more data by the time the user hits the end of the current data?
EGHDK
Okay, I just have that question and one more about this topic, then I'll lay it to rest.
Were you adding to the array adapter or replacing it?
Mark M.
adding
EGHDK
Okay. Thanks. Just curious at this point.
Same scenario (notes application with a bunch of notes), and now I want to implement search. Would it be best to make a search of some sort in the sql query or search the note text from the note pojos?
Mark M.
well, you don't have all 200K note POJOs, so it would appear that searching the database is your only option
plus, you can consider using FTS3/FTS4 for full-text searching, if that makes sense
EGHDK
FTS3/FTS4?
9:35 AM
EGHDK
Is that a lib?
Mark M.
features of SQLite
see the Advanced Databases chapter in the book
EGHDK
Oh. Okay. Thanks
Mark M.
it's your classic sorts of booleans/parentheses/quotes for searching, akin to how you can search on Google
EGHDK
Oh okay. Gotcha.
How would I search without a sqlite db?
Mark M.
that depends on what your backing store is, assuming that you can't fit everything into RAM
EGHDK
What if it was in ram though?
Lets say, smaller scale. 100 objects and each one has a "description" member, and I want to search those members?
Mark M.
iterate over the objects, and call heyDoYouMatchThisSearch() on each
EGHDK
Makes sense. Yeah.
Mark M.
where the implementation of heyDoYouMatchThisSearch() depends on what your objects are and how you are searching
EGHDK
You can go back to Rafael whenever. I have a bunch of other questions that I'm ready to just fire off.
Mark M.
Refael: do you have another question?
Refael O.
nope, as I said before i'll get back tomorrow after trying logging Ion
thanks a lot Mark
Mark M.
OK, wasn't sure if you had questions on other topics
if you come up with anything before the chat ends, let me know
EGHDK: back to you!
9:40 AM
EGHDK
I've been writing plain java unit tests for my public pojo methods. I just found an untested method and was wondering, if theres any testing coverage tools that you know of that can help me in this case.
9:40 AM
EGHDK
Like... tell me if all of my public methods are being tested or not. Does that make sense?
Mark M.
AFAIK, Gradle for Android has some amount of support for Jacoco
I haven't tried it yet
EGHDK
I figure there has to be some utillity that can check and see how much testing coverage I have.
Mark M.
we used to use EMMA, back in the Eclipse/Ant days, but AFAIK Gradle for Android doesn't support EMMA
EGHDK
Gotcha. I'll look into jacoco and Emma. Any others?
Mark M.
none that I am aware of
EGHDK
Target SDK vs Compile SDK. Is compile sdk just used for the IDE to make sure your code is correct/know what to "compile" against? And target sdk is used for deciding which sdk goes in the application?
Mark M.
compileSdkVersion = "what android.jar file, from $ANDROID_SDK/platforms/.../, am I compiling against"
EGHDK
What brought this question up was that in Android Studio I saw an External Libraries drop down in my project view that I never noticed before. And I see 3 platforms in there, so I'm confused why they're there.
Mark M.
targetSdkVersion = "what version of Android was I thinking of when I wrote this code, in case this code runs on a future version of Android, for forwards compatibility"
EGHDK
And does that mean if an external lib is there, does it get packaged with the apk?
Mark M.
that varies by library
EGHDK
So on my app it says Android API 10 Platform... does the entire SDK for Android api 10 get packaged with my app?
Mark M.
no
9:45 AM
EGHDK
Does any android sdk or anything get packaged in my app?
Or does the OS have all the code it needs?
Mark M.
that depends on what "anything" is
third-party libraries are packaged with your app
where the Android Support package counts as third-party libraries
the core Android SDK itself is not
you compile against a local android.jar file that contains stub implementations of all the classes/methods in the JavaDocs
at runtime, you link against a replacement android.jar that has the real code
EGHDK
So support package goes in... that makes sense. because every app could use a different version of support time.
Mark M.
right
EGHDK
stubs... so theyre just empty? why would they make all of the implementations empty
okay, at runtime the android.jar has the real code?
Mark M.
right
EGHDK
So every android phone has an android.jar file that runs everything?
Is it just that one android.jar file... or is it more?
Mark M.
for some definition of "runs everything", yes
Android is somewhat more complex than a single JAR file
EGHDK
like android-10.jar and android-19.jar?
Mark M.
it should only have one API level's JAR
EGHDK
Gotcha. Any more reading that you know of of this. I'm interested in how it all works.
Mark M.
EGHDK
Because I was gonna say... if my phone is stuck on 2.3.3 (api 10) can't I just replace the .jar to the newest lollipop jar?
Mark M.
no, because Android is somewhat more complex than a single JAR file
that's akin to saying that if you replace the spark plugs, your 2006 Prius becomes a 2015 Prius
(if you owned a 2006 Prius, that is)
9:50 AM
EGHDK
Aha. THanks. Makes sense to me.
So the compile time jar is stubbed out, but the real jar is on the device.
Mark M.
right
EGHDK
Cool! Next question. I was wondering if I can send a file named mynotes.eghdkfile in an email, and have myself click the file in the email and have my activity start that file and import the notes I put in there.
Really I guess the question is... can I make my own file type that my app can declare that it knows how to use.
Mark M.
not reliably
there are two ways for you to advertise an activity for that file:
1. say "I want all files with a .eghdkfile extension"
2. say "I want all files with a MIME type of application/x-eghdk"
the problem with #2 is that outside of properly-configured Web servers, nothing else will know to send down that MIME type
9:55 AM
Mark M.
in particular, email clients will see the user attach an .eghdkfile, not recognize it, and use a MIME type of application/octet-stream or something
the problem with #1 is that there is no requirement that the file extension be used with ACTION_VIEW requests
in particular, where the email attachment is served by a ContentProvider, is is fairly likely that that Uri will not end in .eghdkfile
EGHDK
Okay so the problem with #2 is that a webserver might put its on mime type on it?
Mark M.
well, you would have to configure the server to know that .eghdkfile files need to have your custom MIME type
the problem with #2 is that you cannot configure arbitrary email clients of .eghdkfile senders to know about your MIME type
EGHDK
Well, gmail for instance... I can't configure gmamil to know that right? Unless I worked at google?
Mark M.
correct
EGHDK
okay. I thought mime type could be set by the file.
Like the file could declare a mime type.
Mark M.
no
email clients know about common MIME types
so, they'll recognize that a .pdf file should be application/pdf
though that's not guaranteed for all email clients, either
EGHDK
Gotcha. Okay, so the issue with #1 is... I'm unsure of what you mean by the Intent.ACTION_VIEW requets that you brought up.
Mark M.
well, you wrote "have myself click the file in the email"
the only thing an email client is likely to offer, in terms of email attachments, is ACTION_VIEW, to view the attachment
*maybe* they support some sort of ACTION_SEND, to put the attachment someplace else
10:00 AM
EGHDK
Gotcha. So it's up to the email client at that point?
Mark M.
so, when an Android email app gets an email with an application/pdf attachment, it creates an ACTION_VIEW Intent for an application/pdf MIME type, with a Uri pointing to where the PDF can be read in, and calls startActivity()
Refael O.
has left the room
Mark M.
in your case, the MIME type will be something like application/octet-stream, though that will vary by sending email client
EGHDK
Okay, so it'd be up to the email client.
I guess that could work.
Mark M.
and not all application/octet-stream attachments will be yours
EGHDK
Maybe worst case scenario, I can send a link in the email and the link tries to open up in my app, then in the app I can download the file.
But that's for another day.
Thanks Mark!
Mark M.
that can be made to work fairly reliably
EGHDK
Oh wait. How do I announce that I can handle .eghdkfile
Mark M.
and that's a wrap for today's chat
EGHDK
Intent filteR?
Mark M.
yes
EGHDK
Hooray. Okay. See ya tomorrow
Mark M.
as usual, the chat transcript will be posted to https://commonsware.com/office-hours/ shortly
and the next chat is tomorrow at 4pm US Eastern
have a pleasant day!
EGHDK
has left the room
Mark M.
turned off guest access

Friday, July 17

 

Office Hours

People in this transcript

  • EGHDK
  • Mark Murphy
  • Refael Ozeri