Office Hours Transcript: 2021-06-03
Kafran joined
Hello professor. Good night =)
hello, Kafran!
how can I help you today?
I have two questions regarding to the Elements of Kotlin book
sounds good! what is the first question?
1: I’m coming from python to become an Android developer. I missed something about Tests in Kotlin. Where do you suggest to me to look about it?
well, Kotlin is a language, so it does not have tests – tests are part of some larger environment
so, for example, testing on Android is different than is testing on the desktop
and both of those would be different than testing Kotlin/JS or Kotlin/Native for those environments
Eventually I’m gonna dive into Android Development. Do suggest some framework to study about? Is there some I can use either while learning Kotlin to test my code and when I’m on Android?
Do you suggest*
well, I cover testing in Android app development, using Kotlin, in both Elements of Android Jetpack and Exploring Android
that material would be relevant after you have learned more about Android, though
Yep, I read something on Exploring Android. It uses JUnit, right?
yes, for Android, JUnit is the basic test framework
Can I use it to test my Kotlin Code while I’m learning Kotlin?
only if you have some sort of Kotlin/JVM project to put that Kotlin code in
Yes, everything I’m writing while learning Kotlin is running on the JVM
I will try to use JUnit to test my Kotlin function/classes
that seems like a reasonable choice
Can I right my JUnit tests using Kotlin or Do I need to write it in Java?
Can I write*
you should be able to write your JUnit tests in Kotlin
I do it all the time in Android app development, and occasionally in other JVM projects
Ok
The second question is about the Collection chapter.
Once I tried to get a list from a Map like the book example. myMap['some_key'].size and I fall into the null error. At that time I didn’t knew what was happening and I was just reading the chapter today and came across this example
Tad joined
What is the right way to do this?
avoid the use of the [] syntax and use the .get methods?
(BTW, hello Tad – I will be with you shortly!)
ok!
Kafran: do you mean that myMap
is null
?
I mean that myMap['some_key'] can return null, right? The key can be non existant
yes
myMap is a Map of Lists
myMap.get("some_key")
would also return null
in that case, though
So, I can’t use the [] syntax, right?
yes, you can
but with .get I can use myMap?.get(), right?
OK, let me try this one more time: do you mean that myMap
can be null
?
Every Map can be null when retrieving a key, no?
you are conflating the map and the result of retrieving a value from the map
these are not the same thing
I’m talking about this book example:
val oddEven = mapOf('odd' to listOf(1, 3, 5, 7, 9), 'even' to listOf(2, 4, 6, 8))
println(oddEven['odd'].size)
oddEven
can never be null
in that example
and so []
is perfectly fine
This will fail to run, with a compile error:
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type List<Int>?
correct
that is not tied to your use of []
How can I correct this?
with getOrDefault ?
fun main() {
val oddEven = mapOf("odd" to listOf(1, 3, 5, 7, 9), "even" to listOf(2, 4, 6, 8))
println(oddEven["odd"]?.size)
}
this prints 5
you can try it in the Klassbook scratch pad: https://klassbook.commonsware.com/scratchPad.html
ohh… So I can use the ? after []
yes
lol
I tried the ? everywhere
Ok professor. Thats all. Thank you and see you next time =)
sounds good!
Tad: your turn! how can I help you today?
Hi Mark - I posted this question on SO: https://stackoverflow.com/questions/67810037/takepersistableuripermission-via-action-open-document-fails-on-a-custom-document
I’m seeing strange behavior I can’t explain.
I seem to have narrowed it down to something I must be doing in my custom DocumentsProvider but for the life of me I don’t know what.
yes, I saw that – I gave you the upvote 😁
Works perfectly on all devices API 26 and up, fails on 21-25
Ideas of where to look?
remind me again: why are you creating a custom DocumentsProvider
? that is very unusual
I want a seamless user experience for picking photos and videos from Facebook, Instagram, DropBox, etc.
They don’t offer one
ah, right, now I remember
but, in terms of where your problem lies, I have no idea
outside of a trivial example, I have never implemented a DocumentsProvider
, let alone one that supported persistable permission grants
I have it narrowed down I believe to a reconciliation between the Intent passed to SAF and how it stores the resulting doc ID associated with the URI, but sifting through the ASOP source code this part becomes extremely obtuse.
At least to me
yeah, well, the AOSP source tends to get that way
while blackapps is not being super-helpful there, I do agree that you have a lot of extraneous code in the question
I modified the question :)
everything before the handleMediaClipData()
bit seems superfluous to your problem, and you have no code from the DocumentsProvider
itself
Sometimes its hard to tell how much is enough vs. too much.
I’ve also seen tons of responses the other way (post more code)
yeah, though usually that’s with a specific objective in mind
I was waiting for someone who has actually done a DocumentsProvider to weigh in on asking me that.
Otherwise it’s just noise.
yeah, well, there aren’t too many of you on the planet
I already have coded handling the case where the user exceeds their permission grants to prompt them to allow me to download the file for them rather than persist a link, so I guess I’ll just do that for now for devices running < 26
you might see if you can track down the old Vault sample
Not familiar?
that was one of the earliest official (semi-official?) Google samples of implementing a DocumentsProvider
Jeff Sharkey created it
it’s an encrypted provider
OK I will look.
age-wise, it is well within the API 21-25 timeframe
it would be interesting if its persistable permission grants work
if they do, that gives you something to look at to see how Jeff handled it
OK that would be good to see. I could understand it if my stuff failed everywhere. But the fact it works in 26+ is odd.
I agree – if if they don’t with Vault, that starts to make me wonder if they botched persistable grants were broken for third-party DocumentsProviders
until API 26
It’s almost like something changed of how they reconcile doc IDs or something from 26+
A lot changed in that area in 26 btw.
Kafran left
Excellent, I’ll check it out.
more generally, you’re looking for source examples of providers implemented in the 2014-2016 timeframe, to see if they have working persistable permission grants
admittedly, the dust bunnies might have taken over most of those samples
Btw - do you happen to know whether someone has to do something special to access their docs on Google Drive? I notice in my app when I launch the SAF chooser, Google Drive is listed there, and I can choose a file from it without doing anything special. Yet when I attempt to access it via a query on a contentResolver I am getting a permissions error?
When I attempt to access the doc pointed by the Uri returned from SAF
frankly, outside of opening the stream or using DocumentFile
, I tend not to mess too much nowadays with SAF Uri
values
I experimented more with those years ago, but not recently
("those" meaning "doing direct queries related to the Uri
values")
i.e.:
ContentResolver resolver = context.getContentResolver();
cursor = resolver.query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
Gives me a security exception
if they don’t support the OpenableColumns
, there might not be anything to return
do you have the exact error handy?
One sec
InTouchUtils - 4465: Lifecycle: got exception retrieving filename from uri: content://com.reddragon.intouch.facebookdocuments/document/10203482278432769 message was: Access to a document requested but I do not have permission.
sorry, wrong error
hang on
Ahh. Don’t have one handy.
I will try and get one for an upcoming chat
it’s possible it might give me some clues
Well we have a few minutes here. Let me see if I can reproduce it.
Blech
Worked perfectly.
<sigh>
Maybe its another one of those API things.
This was on 28
meaning that you’re wondering if your earlier error was on something older?
Yeah I need to check.
Or it might have been on an emulator that I created brand new and had never logged into Chrome on it. That also is an issue I’ve found.
I have collected a lot of hardware, so I rarely use an emulator
Btw - I checked out JetPack Compose, and was a little disappointed (although not surprised) that it is Kotlin only.
(you had mentioned that last time we talked as a near term needle mover)
on the whole, if it is new and coming from Google in the form of a library, assume it is at least Kotlin-first if not Kotlin-only
Yeah, seems so.
the only substantial stuff that will be Java-first will be framework APIs
Unless it’s Flutter related ;)
Kafran joined
Hilt is from Google also, right?
Is that Kotlin only?
AFAIK Hilt works with Java
That’s what I thought also
Kafran, I see you joined, ask away, we were just chit-chatting at this point!
Hilt is a bit of a Jetpack oddity, in that it is very tightly tied to a non-Google project (Dagger)
Kafran: hi! do you have another question?
Professor, I just reached out to the Lambda part =D. One question: Can I have a lambda with more then 1 parameter?
yes
you should see some examples of that later in the book
Like {x: Int, y: Int -> x * y} ?
yes
Ahh, ok =)
I’m very anxious lol
Se you next time =). Good night Mark and Tad
see*
Nice to see you!
Kafran left
Btw, I might have asked you previously - but why the move to the new chat software
?
Campfire is a service from Basecamp
they attempted to kill it off a few years ago
they kept it around, though I don’t know if they accept new customers
Ah, ok
and with Basecamp’s recent implosion, I figured they might pull the plug
so I wanted to jump before I was pushed
In a way like your comment about Volley vs. okHttp last time
OK last question from me - I now am getting a bunch of lint errors as of API 30 about various and sundry items being deprecated. What is the 'best practice' to deal with this? Do I go through the entire codebase and update to "if < 30 do X otherwise do Y"?
well, it depends on the specifics
sometimes, there is a ...Compat
class that you can use that hides the version check for you
and occasionally the right answer is to move to something else entirely, that happens to work on old and new versions the same
otherwise, yeah, it’s a bunch of if
checks for versions
ok.
As always, thanks for the efforts and time you provide!
Tad left