Mar 7 | 3:50 PM |
Mark M. | has entered the room |
Mar 7 | 3:55 PM |
Mark M. | turned on guest access |
Mar 7 | 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 have so many questions :D
|
Kai H. |
For example about sharing encrypted content, as in this question: https://stackoverflow.com/questions/60256293/fi...
|
Mark M. |
hey, those comments look familiar... :-)
|
Kai H. |
I am a bit astounted that google offers no reliable way to provide content to the outside, especially given that they now promote data encryption in jetpack: https://android-developers.googleblog.com/2020/...
|
Kai H. |
Yes, thanks for the comments :)
|
Kai H. |
I was just wondering if my case is so special that it's just not needed?
|
Mark M. |
I would phrase it more as: your case is not yet common
|
Mark M. |
the AndroidX Security library shipped less than a year ago, IIRC
|
Mark M. |
so, their focus was on in-app use of the encrypted data
|
Kai H. |
And it was in beta when I started using it
|
Mark M. |
right
|
Mark M. |
while we like to think of Google as having this vast army of developers, it is a smaller group than you might think
|
Kai H. |
Still, providing streaming content was a thing for some ppl. I read one SO question about providing "mingled" files in an unmingled version.
|
Mark M. |
one hopes that they will offer their own FileProvider + Jetpack Security solution
|
Mar 7 | 4:05 PM |
Kai H. |
Then again, with the way file handling is going, this might not be needed anymore in the somewhat close future.
|
Mark M. |
if anything, using a ContentProvider to share content will become more important
|
Mark M. |
and that would always have been a requirement if that content were encrypted
|
Mark M. |
my point is that Google can't solve all problems at once
|
Kai H. |
Sure. I do expect a lot of them ;-)
|
Mark M. |
I am sure that you are not the only person with this itch, and somebody -- in Google or outside -- will scratch it eventually
|
Mark M. |
or, perhaps you will scratch that itch yourself, if you choose to
|
Kai H. |
I would not know how, actually.
|
Kai H. |
I was thinking about that. How I could implement something like a "seekable ParcelFileDescriptor" or a similar solution.
|
Mark M. |
theoretically, you could use: https://stackoverflow.com/a/60564953/115145
|
Mark M. |
as I note in my comment on that answer, I did not have a lot of luck working with ProxyFileDescriptorCallback when I tried it three years ago
|
Mar 7 | 4:10 PM |
Mark M. |
but, perhaps others have figured out how to make it work from Java/Kotlin better
|
Mark M. |
the problem that you are trying to solve -- or at least the read-only side of it -- is one that I have poked at off and on for 6-7 years
|
Kai H. |
I think I have stumbled upon this question before in my search and didn't really take it into consideration as an answer
|
Mark M. |
well, that answer just showed up yesterday, as it turns out
|
Mark M. |
it's one of the reasons I was able to get the link for it so fast :-)
|
Kai H. |
I see
|
Kai H. |
I think I'll have a look at it at work next week.
|
Kai H. |
I am a bit satisfied with knowing that I have the somewhat optimal solution for the time being.
|
Mark M. |
read-write, in particular, is a difficult problem
|
Kai H. |
I started as a junior developer around 8 months ago and there are a lot of difficult problems ;-)
|
Mar 7 | 4:15 PM |
Mark M. |
if you have gotten as far as your SO question suggests, you have already gotten further than a lot of senior developers might
|
Kai H. |
Well, I actually "inherited" a Java app.
|
Kai H. |
So I am just poking and extending, but I couldn't write a basic app myself
|
Mark M. |
still, I suspect fewer than 5% of Android app developers have worked with ParcelFileDescriptor, for example
|
Kai H. |
I see
|
Kai H. |
I do try to build an app in my spare time, to better learn and grasp the fundamentals and to get up to the current developments.
|
Mar 7 | 4:20 PM |
Kai H. |
One thing I recently stumbled over was a somewhat simple way to implement concurrency.
|
Kai H. |
I wanted to get a list of chapters from a website and display them in a list.
|
Kai H. |
I ended up using normal Threads, but it feels kinda messy.
|
Mark M. |
a lot of modern Android app development focuses on "reactive" frameworks for concurrency: RxJava and, if you are using Kotlin, coroutines
|
Kai H. |
I am still using Java, because that is what I use at my job
|
Kai H. |
And I wanted to do a simple solution first, before diving into RxJava or something similar
|
Mar 7 | 4:25 PM |
Mark M. |
one could argue that there are no simple solutions with concurrency, only "this hard thing" and "that hard thing" :-)
|
Kai H. |
But trying to make it simple might have maded it more complicated ;-)
|
Kai H. |
Good point. So I guess going into RxJava might be a good idea, even at the start?
|
Mark M. |
um, well, RxJava definitely has a learning curve
|
Kai H. |
But if there are no better "simple solutions", then I will need to use it, I guess
|
Kai H. |
Or dive into kotlin right away as an alternative (given that coroutines are easier to grasp)
|
Mark M. |
"right away" is a strong phrase, but eventually you will want to learn Kotlin and coroutines
|
Mark M. |
for the purposes of a weekend experimental app, whatever you are doing with threads may be sufficient for your needs
|
Mark M. |
you aren't being judged on what the code is, or even what it does
|
Mark M. |
you are judging yourself on how comfortable you feel with Android app development, if anything
|
Kai H. |
I do judge my code myself
|
Mar 7 | 4:30 PM |
Kai H. |
And my current solution just feels icky. Having a "runOnUiThread" with an anonymous Runnable() in my MainActivity is not what I imagine good architecture looks like ;-)
|
Mark M. |
I would describe that approach as "vintage" :-)
|
Mark M. |
in the early days of Android app development, that sort of approach was common
|
Mark M. |
we have been improving, but slowly
|
Kai H. |
According to the google docs one should now use "java.util.concurrent" for background stuff.
|
Kai H. |
To replace AsyncTask in Java
|
Mark M. |
they probably are referring to various forms of Executor
|
Mark M. |
and Executor does not know anything about Android's main application thread
|
Mark M. |
so you would need to pair the Executor with something that does
|
Mark M. |
for example, you might have an Executor-based thread expose its results via LiveData
|
Mark M. |
and have your activity or fragment observe the LiveData -- all observed messages get delivered on the main application thread
|
Kai H. |
I think I just realized what my problem is. I do initialize an RecyclerView.Adapter in my MainActivty and later need to call "notifyDataSetChanged" on it
|
Kai H. |
Do you think one should start with such concepts earlier than later?
|
Kai H. |
LiveData I mean, and RxJava
|
Mark M. |
LiveData on its own is not particularly complicated
|
Mar 7 | 4:35 PM |
Kai H. |
Because I tried to keep my private app as simple as possible and have it grow in iterations, learning on the way.
|
Mark M. |
I cover the use of LiveData in *Elements of Android Jetpack* -- it is a pretty foundational piece of Jetpack-based app development
|
Kai H. |
I think I'll have a look then and will refactor my app using it
|
Kai H. |
Thanks for the books btw
|
Mark M. |
thanks for subscribing! :-)
|
Mark M. |
as Google leans more into Kotlin and coroutines, expect that LiveData will change or be replaced by something more coroutine-based
|
Mark M. |
but, LiveData will still be relevant and usable for a few years, at least
|
Kai H. |
And I guess understanding the concept and thinking about why it exists will remain
|
Mark M. |
most likely
|
Mark M. |
the main application thread will still be "a thing"
|
Mark M. |
and configuration changes are likely to still be around in some form as well
|
Mark M. |
those are the problems that LiveData helps to address
|
Mar 7 | 4:40 PM |
Kai H. |
As I maintain and extend the app at work, I am constantly overwhelmed by it, in different dimensions
|
Kai H. |
There are a ton of Android concepts I do not yet know
|
Kai H. |
And a lot of them are used in strange and mysterious ways
|
Mark M. |
yup, sounds like Android app development :-)
|
Kai H. |
Also, because it is rather old, there is lots of AsyncTask, jumping around with "onPostExecute", hard to follow inheritance and the like
|
Mar 7 | 4:45 PM |
Mark M. |
maintaining older code in a swiftly-changing platform is challenging
|
Kai H. |
And I have two problems with that: It's really hard to understand, making my job very challenging and frustrating sometimes, and it's really old, lowering my worth as an app developer.
|
Kai H. |
Do you have any best practices on dealing with legacy code?
|
Kai H. |
== code you didn't write, that has a certain complexity and is thoroughly undocumented.
|
Mark M. |
umm... I'm a fan of Excedrin for headaches :-)
|
Kai H. |
I see
|
Mark M. |
but, more seriously, that's as much a discussion to have with your team as with an outsider like me
|
Kai H. |
Well, I am my team
|
Mark M. |
oh, I assumed that the "inherited" reference meant that this was something that a team was maintaining and that you joined the team
|
Kai H. |
The guy who wrote the app is my team lead, who I can fortunately ask, but unfortunately he has kinda little time.
|
Kai H. |
Nope. It's mine now :D
|
Mark M. |
OK
|
Mark M. |
in that case, ideally, you budget X% of your time addressing "tech debt", replacing the older approaches with newer ones
|
Mark M. |
your problem, since you are new to Android, is that you are still coming up to speed with the older *and* the newer approaches
|
Kai H. |
Exactly
|
Mark M. |
and for that, there is no great solution, other than patience and fortitude
|
Mar 7 | 4:50 PM |
Kai H. |
I feared as much
|
Kai H. |
That is why I started a personal project, to get experience with newer solutions as well
|
Mark M. |
that's a fine plan
|
Mark M. |
and, if there is an opportunity for you to work on a "green field" app at work, consider trying to do so
|
Kai H. |
I would like that, but at the same time I fear it, as there is so much to do wrong
|
Mark M. |
there are two types of "wrong": it is wrong for the user and it is wrong for you
|
Mark M. |
the focus should be on avoiding "wrong for the user", and fixing it when it crops up
|
Mark M. |
"wrong for you" merely means that things become "tech debt" faster than you would like
|
Mark M. |
that's fairly common when learning a new technolgogy
|
Mark M. |
er, technology
|
Kai H. |
I do focus on architecture quite a bit, which might be more of a hindrance at the start
|
Kai H. |
Especially if one has very little experience and probably don't know yet what good architecture looks like ;-)
|
Mark M. |
also, bear in mind that what constitutes "good architecture" changes with time
|
Kai H. |
I guess "make it work" first and "make it good" later does apply when starting?
|
Mar 7 | 4:55 PM |
Mark M. |
when you are learning? sure
|
Mark M. |
I mean, where practical, try not to do things intentionally awful, but don't worry about whether the architecture is perfect
|
Mark M. |
because today's perfect architecture is tomorrow's tech debt
|
Kai H. |
right now, "good architecture" means "does it's worke somewhat well" and "is extremely readable" to me
|
Mark M. |
that's not a bad target to aim for
|
Mark M. |
over time, you may change your mind as to what you like, and that too is perfectly normal
|
Mark M. |
I mean, I cringe when I look at some of my book examples from my first-generation books
|
Kai H. |
I might also change my mind on what "extremely readable" is ;-)
|
Kai H. |
I know the feeling
|
Kai H. |
But there is also code I am still kinda proud of
|
Kai H. |
So I guess I'll focus more on making the code work and less on how the underlying architecture is for now
|
Kai H. |
And I guess replacing tech debt at work will have to wait until I know *how*
|
Mar 7 | 5:00 PM |
Mark M. |
you may already know how for some things
|
Mark M. |
and, at the risk of sounding self-important... you could do worse than reading *Elements of Android Jetpack* or *Exploring Android* to see how modern development works
|
Kai H. |
I do have ideas, but I have trouble understanding the old code entirely
|
Kai H. |
I am already having those books open and am reading them :D
|
Mark M. |
cool! they should help show how the various Jetpack pieces plug together
|
Kai H. |
One thing I stumbled over was that the books seem to be going into a similar direction
|
Kai H. |
Bot for beginners, both about building an example app
|
Mark M. |
*Elements of Android Jetpack* is a traditional programming guide, and shows both Java and Kotlin
|
Mark M. |
*Exploring Android* is tutorial based, and only shows Kotlin
|
Kai H. |
I see
|
Mark M. |
but in terms of technology, they cover the same ground
|
Mark M. |
it's merely a matter of how you prefer to learn
|
Kai H. |
I remember being confused when reading into one and then the other, thinking "isn't this what the first book does as well?"
|
Kai H. |
And trying to find out the difference between them
|
Mark M. |
I think I covered the differences in the prefaces
|
Mark M. |
if I didn't, I need to fix that
|
Kai H. |
I will have to read them again (or for the first time, might have skipped in one case)
|
Kai H. |
Nah, you have it covered
|
Mark M. |
well, that's a wrap for today's chat
|
Mark M. |
the transcript will show up in https://commonsware.com/office-hours/ shortly
|
Kai H. |
Thank you for your time
|
Mar 7 | 5:05 PM |
Mark M. |
you're welcome!
|
Mark M. |
the next chat is Tuesday at 8:30am US Eastern
|
Mark M. |
have a pleasant day!
|
Kai H. |
Same
|
Kai H. | has left the room |
Mark M. | turned off guest access |