Sugar ORM, List all in Kotlin? Java works, but Kotlin does not - kotlin

The following Java code seems to be fine (no IDE errors),
List<Job> jobs = Job.listAll(Job.class);
When I copy-and-pasted, it was translated into,
val jobs = Job.listAll<Job>(Job::class.java)
But there was an error. Unresolved reference; listAll. What is the correct Kotlin equivalent?
The data class
import com.orm.SugarRecord
class Job : SugarRecord()
{
Sugar ORM: https://github.com/chennaione/sugar

This does not work because child class in Kotlin does not inherit static method from parent. (static does not exist in Kotlin)
You call the method like this:
SugarRecord.listAll(Job::class.java)

Related

Where is this kotlin expression described in the documentation?

I have this kotlin function, and I undersatand that the expression : row.map(Char::digitToInt), converts a Char into an Int.
What I need, is more explanation regarding Char::digitToInt.
How can I relate the use of :: in the kotlin documentation?
Thank's in advance for your reply.
private fun parseInput(input: List<String>): Array<IntArray> =
input.map { row: String ->
row.map(Char::digitToInt).toIntArray()
}.toTypedArray()
As stated in the docs this is a class reference:
Class References: The most basic reflection feature is getting the
runtime reference to a Kotlin class. To obtain the reference to a
statically known Kotlin class, you can use the class literal syntax:
val c = TestClass::class //The reference is a value of type KClass.
Note that a Kotlin class reference is not the same as a Java class
reference. To obtain a Java class reference, use the .java property on
a KClass instance.
It’s also the syntax for method references as in this simple example:
myList.forEach(::println)
It refers to println defined in Kotlin Standard library.

Is it a good idea to pass paramter repository to ViewModel instead of inherited from AndroidViewModel?

The Code A is from https://github.com/android/architecture-components-samples/tree/master/PagingWithNetworkSample
The Code B is from https://github.com/android/architecture-components-samples/tree/master/PagingSample
I know I should use AndroidViewModel instead of ViewModel when I need to use Context to instance a database based Room, just like Code B.
I find the class SubRedditViewModel in Code A doesn't inherited from AndroidViewModel, it pass the paramter repository using construction function.
Is it a good idea to pass paramter repository to ViewModel instead of inherited from AndroidViewModel ?
Code A
class SubRedditViewModel(
private val repository: RedditPostRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
...
}
Code B
class CheeseViewModel(app: Application) : AndroidViewModel(app) {
val dao = CheeseDb.get(app).cheeseDao()
...
}
The moment you inherit AndroidViewModel, your class becomes less unit-testable, as you depend on the Android framework. Also, in your snippet Code B, you lost the ability to inject a test double for your dao, making testing even harder.
In conclusion, try to avoid using framework classes and practice dependency injection (manually or with the aid of a DI framework like Dagger, it doesn't matter). So your snippet Code A would be preferable.

Utils class in Kotlin

In Java, we can create an utilities class like this:
final class Utils {
public static boolean foo() {
return false;
}
}
But how to do this in Kotlin?
I try using functions inside object:
object Utils {
fun foo(): Boolean {
return false
}
}
But when call this method from Java code it need to add INSTANCE. Ex: Utils.INSTANCE.foo().
Then I change to declare it as top-level function (without class or object):
#file:JvmName("Utils")
#file:JvmMultifileClass
fun foo(): Boolean {
return true
}
Then I can call Utils.foo() from Java code. But from Kotlin code I got Unresolved reference compiler error. It only allow be to use foo() function directly (without Utils prefix).
So what is the best approach for declaring utils class in Kotlin?
The last solution you've proposed is actually quite idiomatic in Kotlin - there's no need to scope your function inside anything, top level functions are just fine to use for utilities, in fact, that's what most of the standard library consists of.
You've used the #JvmName annotation the right way too, that's exactly how you're supposed to make these top level functions easily callable for Java users.
Note that you only need #JvmMultifileClass if you are putting your top level functions in different files but still want them to end up grouped in the same class file (again, only for Java users). If you only have one file, or you're giving different names per file, you don't need this annotation.
If for some reason you want the same Utils.foo() syntax in both Java and Kotlin, the solution with an object and then #JvmStatic per method is the way to do that, as already shown by #marianosimone in this answer.
You'd need to use #JvmStatic for that:
In Kotlin:
object Utils {
#JvmStatic
fun foo(): Boolean = true
}
val test = Utils.foo()
In Java:
final boolean test = Utils.foo()
Note that the util class you used in Java was the only way to supply additional functions there, for anything that did not belong to a particular type or object. Using object for that in Kotlin does not make any sense. It isn't a singleton, right?
The second approach you mentioned is rather the way to go for utility functions. Internally such functions get translated to static ones and as you can see they become the static util classes in Java you are searching for, as you can't have standalone functions in Java without a class or enum. In Kotlin itself however they are just functions.
Some even count utility classes to the anti-patterns. Functions on the other hand make totally sense without a class or object whose name hasn't so much meaning anyway.

How to get a kotlin package by reflection

Kotlin reflection library defines KDeclarationContainer, which Represents an entity which may contain declarations of any other entities, such as a class or a package.
this::class returns KClass, which extends KDeclarationContainer, but how do I get the parent KDeclarationContainer (a KPackage?)
There is no KPackage in kotlin now, but you can get a java Package instead, for example:
val pkg:Package = this::class.java.`package`
IF you really want to get a KPackageImpl instance, you can get it from kotlin.jvm.internal.Reflection, but it doesn't make sense, because Kotlin reflect is incomplete yet, for example:
val pkg = Reflection.getOrCreateKotlinPackage(this::class.java, "")
// ^--- there is no methods to get package information like as java.lang.Package,
// since it is a `KDeclarationContainer` rather than a `KPackage`

How to prevent kotlin.Unit object from being stripped by Proguard

Proguard stripes kotlin.Unit standalone object (in Kotlin runtime library), and that causes a compilation error if you are using this type. The following rule does not help with keeping this element (perhaps because Unit is not a class, it's an object):
-keep class kotlin.Unit.** { *; }
We use the Unit type like this:
fun assert(func : Assert.() -> Unit) = Assert().apply(func)
Is there a workaround for this issue or am I missing something?
In Progaurd rules, wildcards after the name of the class indicate nested classes. So get rid of the .** after Kotlin.Unit:
-keep class kotlin.Unit { *; }
Not directly relevant but if you use Kotlin's collections, you need to add the following Proguard rule as well:
-keep class kotlin.collections.CollectionsKt { *; }
Since Kotlin's Standard Library has its own Collections file and it contains top level functions and because files with top-level functions are not a direct Java class, you should use the name Kotlin conventionally uses to store this file as a Java class. From Kotlin's documentation:
All the functions and properties declared in a file example.kt inside
a package org.foo.bar are put into a Java class named
org.foo.bar.ExampleKt.
The name of the generated Java class can be changed using the #JvmName
annotation.
And again don't use the .** wildcard after the class name here.