Mar 21 | 3:55 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Mar 21 | 4:00 PM |
Kai H. | has entered the room |
Kai H. |
Hello
|
Mark M. |
hello, Kai!
|
Mark M. |
how can I help you today?
|
Kai H. |
I am using the Glide image loading library in my application and have "abstracted" the call via a utility method.
|
Kai H. |
Something like "setCroppedImage(...)" with parameters for the View to load into, the image, fallback image etc.
|
Kai H. |
But I am not completely satisfied with this and wonder if I can abstract in a better way
|
Kai H. |
How would you do it?
|
Mar 21 | 4:05 PM |
Mark M. |
off the cuff, I don't know that I would do it at all
|
Mark M. |
if I felt the need... I'd probably use a top-level utility function or perhaps an extension function on a Glide object
|
Kai H. |
The reasone I abstracted it was that Picasso was used before so I had to find all the places where it was used and replace it with the appropriate Glide calls.
|
Kai H. |
We're talking Java btw.
|
Mark M. |
OK
|
Mark M. |
why did you switch from Picasso to Glide?
|
Mark M. |
there's nothing wrong with doing that, of course, but AFAIK Picasso is still supported and still works fine
|
Kai H. |
Because I needed to support image loading via InputStream and Picasso doesn't support that in any way as far as I know.
|
Mark M. |
it has a pluggable API, and a quick search is turning up blog posts and Stack Overflow answers on how to implement one for InputStream
|
Mark M. |
but, anyway, if you've already converted, you're fine
|
Kai H. |
Then my memory failed me :D
|
Mar 21 | 4:10 PM |
Mark M. |
anyway, back to your function...
|
Kai H. |
Maybe it was that I was loading images via an internal ContentProvider (our own FileProvider) and Picasso wouldn't work because it failed with non-seekable file handles.
|
Kai H. |
I'd actually have to go look into my notes at work why I replaced it :D
|
Mark M. |
that's a possibility -- that sort of problem has been a long-standing thorn in my side
|
Mark M. |
Glide has a reasonable terse builder API: Glide.with(fragment).load(url).into(imageView);
|
Kai H. |
Yes, and I tried to emulate that with my own functions, but didn't really know how
|
Mark M. |
if the utility method can add some smarts, and you need those smarts lots of places, then perhaps it's useful
|
Mark M. |
that's beyond what simple methods can do -- you would need to create dedicated builder classes to replicate that sort of API
|
Kai H. |
It actually doesn't. Its only job is to not have to go to all the places again in case I have to replace Glide by something else.
|
Kai H. |
I can "just" replace Glide behind the helper methods.
|
Mark M. |
and if you feel that was worth creating the function, that's a perfectly fine reason
|
Mark M. |
but then whether you abstracted it well or not is really up to you
|
Kai H. |
I am actually not sure, as I really like the builder API and my function (or rather functions, as I have several of them) seem kinda clunky
|
Kai H. |
And don't tell which parameters are passed at which position etc.
|
Mark M. |
all that will be solved when you move to Kotlin :-)
|
Kai H. |
I really wish Java (8) had named parameters or something to make the "builder style" work with normal methods as well
|
Kai H. |
hehe
|
Mar 21 | 4:15 PM |
Mark M. |
I think they added that to one of the later Java versions, but that won't help us on Android for a while
|
Mar 21 | 4:15 PM |
Kai H. |
Which will probably never happen, as my company 50% Java and 40 % Javascript
|
Kai H. |
+uses
|
Mark M. |
I dunno, that remaining 10% has hope!
|
Kai H. |
And 10 % .NET and such
|
Mark M. |
oh, well
|
Kai H. |
But I am really eying Kotlin for things like Coroutines and such
|
Kai H. |
Might give me a way out of AsyncTask hell and too many inheritance layers
|
Mark M. |
more importantly, it's Google's long-term direction
|
Mark M. |
some things simply won't ever be available for Java, such as Jetpack Compose
|
Kai H. |
It's a long way until I can even use something like that
|
Mark M. |
sure
|
Kai H. |
For now I am doing tons of Fragments and deep hierarchies of LinearLayouts etc.
|
Mark M. |
fragments: good
|
Mark M. |
deep hierarchies of LinearLayouts: not so good
|
Mar 21 | 4:20 PM |
Kai H. |
Did you ever implement displaying SVG images that weren't resources?
|
Mark M. |
I think I used the old svg-android several years ago
|
Mark M. |
nothing recently, though
|
Kai H. |
That's what I used too.
|
Mark M. |
(sorry, "the old svg-android library")
|
Mark M. |
there may be better options nowadays
|
Mark M. |
such as a Glide plugin: https://github.com/kirich1409/SvgGlidePlugins
|
Mark M. |
or other ones from https://android-arsenal.com/tag/96?sort=created
|
Kai H. |
I actually use the "Glide SVG Example" which used AndroidSVG
|
Kai H. |
By "use" I mean that I adapted it a little.
|
Mar 21 | 4:25 PM |
Kai H. |
I am often unsure about what libraries I can pull into my project.
|
Kai H. |
How can you make sure a library is "trustworthy"?
|
Mark M. |
what is your specific concern? malware? reliability? something else?
|
Kai H. |
Malware mostly. Reliabilty too
|
Kai H. |
I guess I am just unsure about it :D
|
Kai H. |
And would prefer to only use libs google themselves released and similar.
|
Mark M. |
that's going to be a fairly limiting factor
|
Mark M. |
popular open source libraries are unlikely to contain malware, if for no other reason that somebody would have noticed it in all likelihood
|
Mark M. |
the more esoteric the library, the greater the risk that somebody slips something in that nobody notices
|
Mark M. |
at the same time, the more esoteric the library, the less benefit their is for the attacker, as they won't get as many victims
|
Kai H. |
But take the SvgGlidePlugins example from above. How do I know it's trustworthy and reliable?
|
Mark M. |
skim the code
|
Kai H. |
Is that a common practice?
|
Mark M. |
I doubt it -- you have already expressed more concern about this than the *vast* majority of developers
|
Mark M. |
that's not to say that your concerns are unwarranted
|
Mark M. |
just that they are uncommon
|
Mar 21 | 4:30 PM |
Mark M. |
a simpler check is to see if the library has a manifest and if it is adding anything to your overall app's manifest
|
Kai H. |
I have just been thinking about it
|
Mark M. |
so for example, if this SVG Glide plugin requested READ_CONTACTS as a permission, that would be a warning sign
|
Kai H. |
Definetely :D
|
Mark M. |
the problems we have had with malware from libraries has tended to be from proprietary libraries, particularly ad networks
|
Mark M. |
to date, it hasn't been a big problem for open source libraries
|
Mark M. |
that does not mean that it cannot someday bite us in the posterior, just that it has not happened significantly to date
|
Kai H. |
I think I'll relax when it comes to importing
|
Mark M. |
another thing you could do, if you wanted, is compile the library yourself from source, rather than rely on a Maven repository's artifact
|
Mark M. |
there's a whole research area on 'reproducible builds' for trying to determine if a certain compiled app really came from the expected source code
|
Kai H. |
Ah yes, some OS' are big on that. Debian for example iirc.
|
Mark M. |
right
|
Mar 21 | 4:35 PM |
Mark M. |
(though I think it's more a Gentoo thing, if they're still around)
|
Mark M. |
pre-compiled artifacts are very convenient, but they open up other attack avenues
|
Kai H. |
How so?
|
Mark M. |
for example, suppose somebody hacked into Maven Central or JCenter and replaced a library with a malware-laden one
|
Mark M. |
developers would pick up that library and use it
|
Mark M. |
the authors of the library might not notice the switch
|
Mark M. |
and the source code would not reflect the malware, since the malware did not come from the source
|
Mark M. |
so, for projects for which these sorts of concerns are huge (e.g., the Guardian Project's apps), they tend to build completely from source
|
Mark M. |
and there are layers upon layers that you can do for defensive measures (e.g., airgapped build machines)
|
Mar 21 | 4:40 PM |
Kai H. |
That sounds like you need a lot of manpower
|
Mark M. |
yes, or small projects
|
Mark M. |
basically, the keys are: how big of a target is your app, and what would be the outcome of a successful attack?
|
Kai H. |
So if it was really important, I'd get the source, confirm it's not doing anything strange and then use that
|
Kai H. |
And if there are any updates, I have to reconfirm.
|
Mark M. |
yes
|
Mark M. |
yes
|
Kai H. |
I see
|
Mark M. |
at least for open source libraries -- that may or may not be possible for commercial ones
|
Kai H. |
I guess my app is not big enough of a target :D
|
Mark M. |
here, 'big' either means lots of users, lots of $$$$, or at-risk users
|
Mark M. |
so, for example, Signal Messenger isn't exactly Facebook-scale and only sorta has lots of $$$$, but I'm sure there are "nation-state actors" trying to figure out how to get stuff into their builds
|
Mark M. |
this sort of thinking is a key reason why I do not like App Bundles and I do not like Google's signing service
|
Mark M. |
if Google signs the APK, Google has control over what is in the APK
|
Mar 21 | 4:45 PM |
Kai H. |
Yes
|
Mark M. |
and Google might change what is in the APK, whether of their own volition or not
|
Mark M. |
there are lots of places where unpleasant things can happen
|
Mark M. |
and, on the whole, our industry is doing a craptastic job of dealing with them
|
Mark M. |
eventually, there will be some incident that will change behaviors
|
Kai H. |
Weren't there some already? I remember NPM having some malicious packages?
|
Mark M. |
oh, NPM has had problems from time to time
|
Mark M. |
while I'm nervous about GitHub getting too big, I don't mind them buying the NPM stuff
|
Mark M. |
because GitHub probably has better resources for dealing with those sorts of problems
|
Mark M. |
fortunately, we haven't really had the same problem happen yet in the Android ecosystem
|
Mark M. |
I suspect that has a lot to do with luck
|
Kai H. |
Yes. I guess we pull in less stuff?
|
Kai H. |
That too, mayb :D
|
Mar 21 | 4:50 PM |
Mark M. |
Android apps might use fewer dependencies than Web apps, but I think we're catching up
|
Kai H. |
I wonder if we should though
|
Mark M. |
it's all a matter of priorities
|
Mark M. |
and these sorts of concerns usually aren't a priority
|
Mark M. |
similarly, our ability to deal with pandemics wasn't a priority
|
Mark M. |
things aren't a problem until they're a problem
|
Kai H. |
He
|
Kai H. |
he
|
Kai H. |
I can see that in the code I have inherited
|
Mark M. |
similarly, these sorts of concerns tend not to worry the firms that I help
|
Mark M. |
so, I try to improve their practices "around the edges" as best I cant
|
Mark M. |
er, as best I can
|
Mark M. |
but a wholesale revision to how the app gets built isn't something I can make happen
|
Kai H. |
What kind of help do they usually want? And what do you recommend the most often?
|
Kai H. |
How the app gets built?
|
Kai H. |
What do you mean by that?
|
Mar 21 | 4:55 PM |
Mark M. |
the sorts of stuff we have been discussing here, along with other mechanics of the build process (e.g., do we fail the build on Lint errors?)
|
Kai H. |
Oh, I was thinkiung more generally. I see.
|
Mark M. |
if I am contributing directly to the project, I have a voice in those sorts of things, just like any other developer
|
Kai H. |
Do you have your "Android App Development Best Practices" somewhere in your books?
|
Mark M. |
"best practices" tends to be the sort of thing that "lies in the eye of the beholder"
|
Mark M. |
particularly at the level of projects
|
Kai H. |
I see
|
Mark M. |
what is a "best practice" for a solo developer will not resemble what is a "best practice" for a major firm
|
Mark M. |
so, I tend to steer away from that and focus more on "nuts and bolts" sorts of things
|
Kai H. |
Which are?
|
Mark M. |
how do you use ConstraintLayout? what is a viewmodel and what does it model (and how do we view it)? how do I get SQLCipher for Android working?
|
Kai H. |
Oh ok
|
Mark M. |
the things that you see in my books
|
Kai H. |
I think I got it
|
Mark M. |
I have gotten a bit more into architectural topics, but not too deep, as that's an area that is still undergoing a lot of changes
|
Mar 21 | 5:00 PM |
Kai H. |
And one has to find that out for oneself, I guess
|
Kai H. |
Depending on the project and environment and such
|
Mark M. |
to an extent, yes
|
Mark M. |
there are lots of conference talks and Medium posts and stuff with people extolling the virtues of one practice or another
|
Kai H. |
Which makes it kinda hard to pick one
|
Mark M. |
right
|
Kai H. |
Especially when having little experience and there is already something in place
|
Kai H. |
Or only having little experience.
|
Mark M. |
so, personally, I've been just trying to echo Google's recommendations and not go a lot further
|
Mark M. |
Google has been getting a bit more opinionated on architecture in recent years, so I have pivoted a bit to match
|
Kai H. |
Do you agree with them?
|
Kai H. |
Or rather take them as a baseline?
|
Mark M. |
"baseline" is a fairly reasonable description
|
Kai H. |
And leave it to the reader to deviate from it
|
Mark M. |
I have a few places where I depart somewhat from what they recommend, but not many and my changes are not outlandish
|
Mark M. |
but, that's a discussion for another day
|
Kai H. |
I think it's nice having a baseline to use when starting out
|
Mark M. |
that's a wrap for today's chat
|
Kai H. |
Instead of being confused by too may medium posts
|
Mark M. |
the next one is Tuesday at 8:30am US Eastern
|
Kai H. |
Thanks
|
Kai H. |
Stay healthy :D
|
Mark M. |
the transcript for this one will appear on https://commonsware.com/office-hours/ in a bit
|
Mark M. |
you too!
|
Kai H. | has left the room |
Mark M. | turned off guest access |