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

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 []

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?

 

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?

 

you should see some examples of that later in the book

Like {x: Int, y: Int -> x * y} ?

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