Mark M. | has entered the room |
Mark M. | turned on guest access |
Dec 27 | 3:55 PM |
Chandra S. | has entered the room |
Mark M. |
hello, Chandra!
|
Mark M. |
how can I help you today?
|
Dec 27 | 4:00 PM |
Chandra S. |
Hi Mark
|
Chandra S. |
Is it still recommended to use Asynctask? Compare to Loader?
|
Mark M. |
that depends on who is making the recommendation :-)
|
Mark M. |
some would say "neither, use RxJava" or something like that
|
Mark M. |
personally, given the choice of those two, I would use a retained fragment with an AsyncTask
|
Chandra S. |
What is your recommendation? :-)
|
Chandra S. |
What is "retained fragment"?
|
Mark M. |
a fragment on which you call setRetainInstance(true)
|
Mark M. |
to say "hey, when the activity is destroyed and recreated due to a configuration change, please just pass off this fragment to the new activity, instead of destroying and recreating the fragment"
|
Chandra S. |
Is it for not reloading when the device rotated or some other events?
|
Chandra S. |
So the fragment is saved in the memory when the activity destroyed?
|
Dec 27 | 4:05 PM |
Mark M. |
correct
|
Dec 27 | 4:05 PM |
Chandra S. |
So, you recommend Loader when DB-related case?
|
Mark M. |
the only time I will use a Loader personally is if I am querying a ContentProvider, and sometimes not even then
|
Chandra S. |
Or on what example of case do the Loader best use?
|
Mark M. |
other people are happier with the Loader framework than I am
|
Chandra S. |
Ah, I see..
|
Mark M. |
this blog post from ~3 years ago sums up my feelings: https://commonsware.com/blog/2014/03/31/cwac-lo...
|
Mark M. |
the concerns that I present there are a bigger issue for libraries (like my now-discontinued CWAC-LoaderEx)
|
Mark M. |
and so for a private project, having a loader that does not implement the entire contract can be fine
|
Chandra S. |
I also still didn't get the function of Content Provider itself if I didn't want my app to publish anything to other apps
|
Mark M. |
I agree -- I only implement a ContentProvider if I am publishing content to other apps
|
Dec 27 | 4:10 PM |
Chandra S. |
So, basically, I'm already good with only Asynctask and retained fragment right?
|
Mark M. |
there is nothing wrong with that combination IMHO
|
Chandra S. |
I just worried since other tutorials show that Content Provider and Loader is a must
|
Mark M. |
the authors of those tutorials are welcome to their opinions, even though I do not share them
|
Chandra S. |
Yep I'm on your side, Mark.. mostly because I still didn't understand Loader & Content Provider much :-D
|
Chandra S. |
I have another question regarding ViewHolder
|
Chandra S. |
What is tag on ViewHolder?
|
Mark M. |
I assume that you are referring to using the view-holder pattern with an AdapterView, such as a ListView
|
Chandra S. |
I read description in your book but what I understand is it only give a cache to the View
|
Chandra S. |
Yes correct
|
Mark M. |
a view holder pretty much is just that: a cache of findViewById() lookups for widgets inside the ListView row (or the equivalent for other AdapterViews)
|
Dec 27 | 4:15 PM |
Mark M. |
with RecyclerView, a RecyclerView.ViewHolder sometimes gets used for more stuff (e.g., as a presenter or controller for that individual RecyclerView item)
|
Mark M. |
but that's less common with the view holder pattern with ListView
|
Mark M. |
the tag is simply a way of attaching the view holder to the ListView row, as ListView deals only with rows
|
Mark M. |
in particular, it is a way of attaching the view holder to the row without having to create some custom View class to do so, which is a pain
|
Mark M. |
the name "tag" comes from Java Swing in the 1990's
|
Mark M. |
(and I do not know why Swing named it "tag")
|
Chandra S. |
If I'm just starting up, can I just skip the ListView and directly use the RecyclerView?
|
Mark M. |
sure
|
Mark M. |
in general, for new development, I recommend RecyclerView
|
Mark M. |
it is more flexible, if somewhat more cumbersome to set up initially
|
Chandra S. |
Thanks for the clarification, Mark
|
Chandra S. |
Regarding the Layout Inflater, do LayoutInflater.from(context) and getLayoutInflater() give the same result?
|
Mark M. |
AFAIK, if context is an Activity, those are equivalent
|
Dec 27 | 4:20 PM |
Mark M. |
personally, I trust getLayoutInflater() more
|
Mark M. |
I only use LayoutInflater.from() for non-activity cases (e.g., managing a View from a Service)
|
Chandra S. |
I see..
|
Chandra S. |
I have another question on ContractClass in SQLite
|
Mark M. |
I do not know what ContractClass is, sorry
|
Chandra S. |
I mean the Contract in SQLite
|
Chandra S. |
Must we specify Contract? Can we specify with string directly when accessing from other classes?
|
Mark M. |
I still do not know what you are referring to
|
Dec 27 | 4:25 PM |
Chandra S. | |
Chandra S. |
Something like this
|
Mark M. |
the Contract pattern is mostly for ContentProvider, and frankly is not all that useful there either IMHO
|
Mark M. |
you do not need a Contract class to work with SQLite
|
Chandra S. |
I see.. that's why I confused
|
Chandra S. |
So if we didn't use ContentProvider, just use SQLiteOpenHelper will be enough right?
|
Mark M. |
sure
|
Chandra S. |
I finally understand some stuffs after this conversation :-) thanks, Mark
|
Dec 27 | 4:30 PM |
Chandra S. |
Most probably last question
|
Chandra S. |
Regarding the network connection, what are your recommendation? Picasso, retrofit, okhttp, or other else?
|
Mark M. |
um, well, yes to all three of those
|
Mark M. |
OkHttp is a general-purpose HTTP client
|
Mark M. |
and, it optionally plugs in as the engine behind higher-order APIs for images (Picasso) and REST-style Web services (Retrofit)
|
Mark M. |
which of those three you use depends a lot on what sorts of HTTP requests you are making
|
Mark M. |
for example, if you are not working with a REST-style Web service, you have no need for Retrofit
|
Mark M. |
on the whole, I have been happier with that trio of Square libraries than anything else that I have tried (Volley, Ion, HttpClient)
|
Chandra S. |
So if my purpose is to use REST and to download images, combination of Picasso and Retrofit would be good right?
|
Dec 27 | 4:35 PM |
Mark M. |
yes
|
Chandra S. |
Or better to use Picasso or Retrofit only if I consider the app size?
|
Mark M. |
sorry, but I do not understand that question
|
Chandra S. |
Can I just choose Picasso or Retrofit for both purpose (REST and image downloading)?
|
Mark M. |
no
|
Chandra S. |
I see.. ok..
|
Chandra S. |
For uploading image like Instagram/FB apps, picasso would be enough right?
|
Mark M. |
Picasso only downloads, unless I missed a part of its API
|
Mark M. |
it is an image loader, that happens to support HTTP/HTTPS as a source of images
|
Chandra S. |
Ah I see.. So, what is your recommendation on image uploading?
|
Mark M. |
for uploading images, you might be able to use Retrofit, and if not you would be looking at using a general-purpose HTTP client API like OkHttp
|
Mark M. |
(and Retrofit would only be relevant if the image-uploading were part of a REST API)
|
Mark M. |
image uploading is a complicated topic, in part because your client-side options are limited based on what the server wants
|
Dec 27 | 4:40 PM |
Ace R. | has entered the room |
Chandra S. |
You meant the network related on client side?
|
Ace R. |
hi all
|
Mark M. |
I mean that if the server wants the images to be base64-encoded and put into a form field, that is different than expecting you to do an HTTP PUT of the image to a REST-style URL, which is different than other approaches
|
Mark M. |
Chandra: let me take a question from Ace, and I will be back with you in a bit
|
Mark M. |
Ace: your turn! do you have a question?
|
Chandra S. |
Ok, Mark, many thanks :-)
|
Ace R. |
Hi Mark, I'm trying to query my product table using AsyncQueryHandler but I don't understand why Im getting this error: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
|
Ace R. |
does that mean the cursor did not return a row?
|
Mark M. |
no
|
Mark M. |
the "size of 1" means you got one row back
|
Ace R. |
what does the -1 Index -1 mean?
|
Mark M. |
IIRC, the index -1 part means that you did not call one of the move...() methods to position yourself on a valid row
|
Mark M. |
by default, a Cursor is positioned before the first row
|
Mark M. |
if you are expecting a one-row result, you typically call moveToFirst(), then retrieve values from that row via getString(), getInt(), etc.
|
Dec 27 | 4:45 PM |
Mark M. |
if you are expecting N rows, a while(cursor.moveToNext()) loop works, where you process each row inside the loop
|
Ace R. |
hmmn okay. thanks. that makes sense. I just tried it now and it works
|
Mark M. |
Android's Cursor is fairly typical of cursor-style APIs, but this particular hiccup is fairly commonplace
|
Mark M. |
I'm glad that it is working for you now
|
Mark M. |
let me take another question from Chandra, and I will be back with you shortly
|
Ace R. |
I was wondering is it best practise to use AsyncQueryHandler?
|
Mark M. |
(personally, I just use my own threads)
|
Ace R. |
or is there some other way?
|
Mark M. |
Chandra: your turn! do you have another question?
|
Ace R. |
okay
|
Dec 27 | 4:50 PM |
Mark M. |
Chandra: if you come up with another question, let me know
|
Mark M. |
Ace: back to you! do you have another question?
|
Ace R. |
yes please could you elaborate what you mean by using your own thread?
|
Ace R. |
how to I do that?
|
Mark M. |
when I want to query a database, I fork a thread and do the query there
|
Mark M. |
in particular, I never wrap a database in a ContentResolver
|
Ace R. |
fork a thread? using runnable interface?
|
Mark M. |
or a subclass of Thread, or an Executor, or RxJava
|
Mark M. |
lots of threading options
|
Ace R. |
ohhh interesting. how comes you never wrap it in ContentResolver?
|
Ace R. |
I always want to get away from contentresolver
|
Mark M. |
IMHO, it adds no value for the in-app case
|
Mark M. |
(BTW, I really meant ContentProvider, not ContentResolver)
|
Mark M. |
for publishing content to third-party apps, ContentProvider is fine
|
Mark M. |
for using content within an app, ContentProvider adds overhead and complexity for little added value IMHO
|
Ace R. |
okay yes. that's good to know. I just find all the syntax weird especially having to join multiple tables
|
Mark M. |
agreed
|
Ace R. |
I would like to option to send raw sql query
|
Ace R. |
because Im quite good at sql
|
Mark M. |
just work with SQLiteOpenHelper and SQLiteDatabase directly
|
Mark M. |
you may still want to centralize that logic
|
Dec 27 | 4:55 PM |
Mark M. |
but you do not have to sit it behind the ContentProvider facade
|
Ace R. |
ah yes. that is what im looking for.
|
Ace R. |
my tables are getting bigger
|
Ace R. |
and more
|
Ace R. |
so I have to join multiple tables
|
Ace R. |
and the syntax just getting me confuse
|
Ace R. |
okay no more questions
|
Ace R. |
Thanks for your help today.
|
Mark M. |
you are very welcome!
|
Mark M. |
Chandra: if you have another question, go right ahead
|
Dec 27 | 5:00 PM |
Chandra S. | has left the room |
Mark M. |
that's a wrap for today's chat
|
Mark M. |
the chat transcript will be posted to https://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is Thursday at 9am US Eastern
|
Mark M. |
have a pleasant day!
|
Ace R. | has left the room |
Mark M. | turned off guest access |