Office Hours — Today, April 26

Thursday, April 21

Apr 26
7:20 PM
Mark M.
has entered the room
Mark M.
turned on guest access
7:30 PM
jth
has entered the room
Mark M.
hello, jth
jth
Hello
Mark M.
how can I help you today?
jth
Just joined today
I have a hybrid Android App, webview and native views
I am having issues with Volley and sending the cookies from the webview via Volley to API calls
Michaelidle
has entered the room
Mark M.
"However on my volley calls to the APIs, the cookies are not being sent" -- are you doing something to get the cookies over to Volley?
(BTW, hello Michaelidle -- I will be with you shortly!)
jth: I don't recall Volley having its own cookie code, though I wasn't paying much attention to that when I last looked at the Volley source
Volley delegates HTTP I/O to HttpURLConnection on Android 2.3+
jth
Well first of all, is volley still recommended?
Mark M.
well, it's better than using HttpURLConnection directly
jth
I recently added it to the app, however is seems like documentation is lacking
Mark M.
dental surgery is better than using HttpURLConnection directly
personally, I would lean towards OkHttp3
for the documentation and support reasons, plus packaging
but Volley is OK
jth
I was looking into that and retrofit
Mark M.
Retrofit blends nicely with OkHttp3
jth
most api calls are json and in house apis
Mark M.
anyway, HttpURLConnection knows nothing about android.webkit.CookieManager AFAIK
jth
ok
Mark M.
it has its *own* CookieManager class (java.net.CookieManager)
7:35 PM
Mark M.
so if you are going to synchronize cookies, AFAIK you have to do that yourself
I haven't looked into the details of exact mechanisms for that
jth
Is seems like many people recommend a persistent cookiestore, but not many examples of that
Mark M.
persistence is a separate issue
jth
Yes I need to maintain the cookies between the webviews and apis calls and store them
Mark M.
since there are cookie-related APIs exposed on both sides, it seems plausible for you manually schlep cookies from the WebView side over to the HttpURLConnection side
but, again, I haven't played with that personally
jth
ok
Mark M.
let me take a question from Michaelidle, and I'll be back with you in a bit
jth
sure
Mark M.
Michaelidle: your turn! do you have a question?
Michaelidle
So I have been slowly been reworking my Adapter, ListView, Repository code. I removed all of the adding to the List<> that happened on the background thread, so that seems to work well, because now I'm not getting "the data in the adapter has changed, remember to call notifyDataSetChanged". But sometimes I still feel the need to add to that List<> backing that adapter.
So my question is, do you have any recommendation for modifying a List<> that could sometimes be held in an adapter and sometimes it's not.
Mark M.
whoever is doing the adding needs to know if it is in an adapter or not
I don't see much in the way of an alternative
7:40 PM
Michaelidle
Yeah, it's just that I have this Repository which you can call getList() on, and sometimes it's used in a service, and sometimes it can concurrently be used on my Activity.
Mark M.
that's a scary architecture, IMHO
I'd keep what the UI is displaying a bit more separate from what the back-end is manipulating
for example, you could have your service still update the List<>
however, the UI is working off of a copy of the List<>
your service also raises an event bus event (or the equivalent) to say "hey! the master list is updated!"
perhaps including information on what actually changed
then, the UI can receive that event and do whatever modifications are necessary to its copy
this is a bit on the MVVM side of the GUI architecture approaches, though I'm no expert
Michaelidle
That gives me some ideas. Thanks
Mark M.
the UI is working off of a view-model, while the service manipulates the real model
let me switch back to jth, and I'll return to you in a bit
jth: your turn! do you have a question?
jth
yeah so I was prototyping with Retrofit today
7:45 PM
Aaron H.
has entered the room
jth
If I want a sync call, do I need to do it on another thread? I was getting a onMainThread exception
Mark M.
(hello, Aaron -- I will be with you shortly!)
jth
I was able to use it async with calls backs, but when I want a sync call
Mark M.
jth: Retrofit offers two models: synchronous or asynchronous
basically, whether the interface-defined method returns the results or takes a Callback as a parameter
both work, but the synchronous approach needs to be done on your own background thread
jth
ok that is what I thought
Mark M.
there's a pair of stone tablets somewhere; one has "thou shalt not do network I/O on the main application thread" carved into it
jth
what is the current recommended way for background threads? Currently the inherited app uses classes extended from Thread.
Mark M.
nothing wrong with that
jth
If you talk about it in the book, you can point me there
ok
Mark M.
I demonstrate lots of different threading approaches in the book, as one size does not fit all
jth
ok i have one follow up to the cookie issue, but you can go around the room and I can wait
Mark M.
OK
Aaron: your turn! do you have a question?
7:50 PM
Aaron H.
I actually have just started the book and was wanting to check this out and see if I could glean any information from others questions
i don't have any specific questions...yet
Mark M.
OK
you can also peruse several years' worth of chat transcripts at https://commonsware.com/office-hours/
this chat's transcript will be posted there shortly after the chat ends
if you come up with a question, let me know, so I can include you in the round-robin
Aaron H.
that's great! thank you
Mark M.
meanwhile...
Michaelidle: back to you! do you have another question?
Michaelidle
Yeah, so I've been using an interface to listen to my Repository when a new item is added in the DB, and then my activity get's the callback, and it adds the item in my list.
Works well, but I am curious if I cause a memory leak in an Activity if I don't "unregister" the listener.
Because my Repository is a Singleton.
Mark M.
if the repository can reach the activity via the listener, then yes, by default, failing to unregister will cause a leak
7:55 PM
Mark M.
the typical approach is to have the listeners held onto weakly by the singleton
e.g., the singleton has a WeakReference<Listener> instead of a Listener
then, the Listener (and things downstream from it, like the activity) can get garbage-collected despite the singleton knowing about them
Michaelidle
That's a great way to think about it. I've actually never used a WeakReference. Does that just automatically get removed after some condition is met?
Mark M.
the singleton, as part of getting the Listener out of the WeakReference<Listener>, will check for null, indicating that the Listener had been garbage-collected
yes, if there are no strong (i.e., normal) references to the object, the WeakReference gets cleared out, so it holds null instead of the former object
Michaelidle
Gotcha. But creating an unregister that happens onStop() will also do the trick... instead of a WeakReference.
Correct?
Mark M.
yes... assuming you don't screw up somewhere and forget to unregister
there are also edge cases, like unhandled exceptions, to consider
so, skipping the WeakReference can be done, but you should do other things to try to watch for leaks, like integrate LeakCanary
Michaelidle
So in an unregister, I would just set the Listener = null and that should be alright?
Mark M.
it clears up that potential leak
I offer no guarantees about any other potential leaks in your code :-)
Michaelidle
Thanks
Mark M.
jth: back to you! do you have another question?
jth
My code heavily uses the Apache HTTP client. I know in 5.x Google Deprecated it, and now in 6.0 they have removed it. I am currently using useLibrary 'org.apache.http.legacy' to continue to be able to build in Android Studio.
8:00 PM
jth
I realize switching over to HttpURLConnection is recommended, but having this prioritized over other item can be difficult.
Is there a change useLibrary 'org.apache.http.legacy' could be pulled in the future?
Mark M.
there are two separate issues:
1. will the built-in HttpClient be removed in the future? unlikely, as that will break all sorts of legacy apps
2. will useLibrary ... be removed, to force ongoing development off of HttpClient? I can't rule that out
that comes from the Android Plugin for Gradle
and so even if it is removed in some future version of that plugin, you still have time, simply by not upgrading to a newer plugin
Michaelidle
I'm not Mark, but just use OkHttp. I know that's not really an answer, but it's the goto client in Android, and it's included in Android (I forget which version) by default AFAIK.
Mark M.
eventually, you may start to feel the pinch from that
Michaelidle: more accurately, HttpURLConnection starting with Android 4.4 is based on an earlier version of OkHttp3
jth
ok just trying to get enough of a case to get PMs to buy into setting aside to for tech debt
Mark M.
mostly to get Square's work on supporting SPDY
jth: more so than rushing to move off of HttpClient, I would recommend that you pick one HTTP stack and stick with it
jth
ok
Mark M.
that could be Apache's independent packaging of HttpClient for Android, or OkHttp3, or Volley, or using HttpURLConnection directly
or Ion or other less-common alternatives
8:05 PM
Mark M.
you're stuck with WebView being separate, but there's nothing that you can do about that :-(
8:05 PM
jth
just thought moving to volley was the right idea for APIs call, no wondering if that was the right decision.
Mark M.
IMHO, OkHttp3 > Volley > HttpClient > torture > HttpURLConnection
jth
And as you stated I can use OkHttp3 with retrofit
Mark M.
yes, you can configure an OkHttpClient once and use that both directly (e.g., binary downloads) and with Retrofit (e.g., Web service calls)
jth
ok that is a start. Just hard to make changes to a 5 year+ app in the 1,000,000 - 5,000,000 download range
Mark M.
yeah, that's not going to be fun
jth
and multiple developers and contractors in it before me
thank you for the help and advice
Mark M.
you are very welcome
Michaelidle: back to you! do you have another question?
8:10 PM
Aaron H.
has left the room
Michaelidle
I've used interfaces in java for years. Even before I started Android development. And this ListView/Adapter/Repository issue I've been thinking about them a lot, and may have started to overthink them. I actually have no idea why they work at all. So this is me just trying to clear my head (I think I've been starring into this issue for too long). So onStart() I register a onListChangedListener() and I create an anonymous inner class. Why do the callbacks even work. Is this because of Polymorphism?
Mark M.
"I actually have no idea why they work at all" -- they are stitched together by Santa's elves during the off-season
but an anonymous inner class is just an implementation of your interface (or subclass of some other class)
the fact that it is anonymous is syntactic sugar, to save you from declaring YetAnotherLongJavaClassName somewhere
polymorphism in Java is enabled by interfaces
I don't know if anything of what I wrote helped
Michaelidle
Hahah. I feel like I've taken them for granted... and then they make sense... and then they don't. What caused me to go insane was, I had Repository.deleteItem() being called in an IntentService, which made the listener go off in my Activity and I would call notifyDatasetChanged(), but my code wasn't doing anything, because it wasn't on the main thread. So I was just confused, how something that was "seemingly" happening in onStart() (which I know is not the case) was happening off the main thread.
8:15 PM
Mark M.
keeping things straight with threads takes getting used to
OK, if either of you have any questions, just chime in
Michaelidle
Is it anything besides syntactic sugar? I can access things from my activity in the AIC, like the adapter, and call notifyDatasetChanged()
Mark M.
well, you could do the same thing from a named inner class
the anonymous bit is syntactic sugar
Michaelidle
So if I wanted to make it a separate class (like a inner static class), I wouldn't be able to pull that off then (getting my Activitys members)
Mark M.
a static class has no access to the members of the outer class
an inner class does
(I wish they had better names for those, but that's a separate issue)
8:20 PM
Michaelidle
My class could take some of those members in the constructor right?
Mark M.
sure
jth
I did find this post about cookies webview and httpURLConnection - http://stackoverflow.com/questions/36800094/and... - what is your opinion of this?
Mark M.
um, that looks like the link you posted at the outset of the chat
Michaelidle
Okay. Thanks Mark. You eased some of my worrying. Silly how 1 problem made me rethink ~4 years of using interfaces. Hahaha
Mark M.
Michaelidle: glad I could be helpful
jth: are you sure that's the post that you are referring to? it looks like an unanswered question that you (or somebody with your initials) asked
Michaelidle
jth
8:25 PM
Michaelidle
I did something like that recently.
I got a cookie in my web view, that I had to push through to my okHttpClient. Let me look up my code and see what I did really quick. Maybe it'll give you some direction.
Mark M.
what I was envisioning was something akin to http://stackoverflow.com/a/18061610/115145
the comments suggest that this code would need some amount of updating to reflect changes to WebView, which was seriously overhauled in Android 4.4
jth
Michaelidle
Mark, while I look for my code... I do have a question still regarding adapter and adding/removing/updating the items. I do want it to look fairly smooth. The way I was doing it before was replacing the whole adapter, so that sucked, but now It looks alright, but I'm not sure how updating a Convo in List<Convo> would work. My Convo objects are immutable, so I would need to remove and then add.
Mark M.
jth: yeah, that's the post I was just looking at
there's promise there, but it looks like it may need work
jth
ah ok
Mark M.
Michaelidle: well, if you were using RecyclerView, you would use notifyItemChanged()
8:30 PM
Michaelidle
jth I saved the cookie in my code to a pref. I guess it's a little wacky, but it works. String gotCookie = CookieManager.getInstance().getCookie(authUrl);
Mark M.
off the top of my head, I'm not sure how I would handle that with ListView, sorry
Michaelidle
Do you know any tips in the adapter to make it smooth? I know someone recommended hasStableIds which I haven't looked into yet.
jth
thank you again
Mark M.
Michaelidle: sorry, nothing is leaping to mind off the cuff, with immutable items in the adapter
and that's a wrap for today's chat
Michaelidle
I guess the smooth part is a silly question. Yeah, I think RecylclerView will be a good choice. Just curious really if there's a best bet for Adapter and ListView, but you said the next book update. So I guess I'll have to wait!
Mark M.
I'm not sure what you're referring to with the next book update
I have one due out next week
but I don't think I have anything new related to ListViwe
er, ListView
anyway, the chat transcript will be posted to https://commonsware.com/office-hours/ shortly
the next chat is Thursday at 4pm US Eastern
have a pleasant day!
jth
has left the room
Michaelidle
has left the room
Mark M.
turned off guest access

Thursday, April 21

 

Office Hours

People in this transcript

  • Aaron Houghton
  • jth
  • Mark Murphy
  • Michaelidle