Posts

Showing posts with the label Kotlin

Converting Kotlin's KClass To Regular Class In Java

Answer : The functionality does exist, just not where it seems to, as java is an extension property. Use the method JvmClassMappingKt.getJavaClass . In Kotlin, extension methods (and property getters/setters) are implemented as static methods of their containing class. If you look at the source for .java ( Ctrl + Q ), you can see that it is implemented in JvmClassMapping.kt . As the function is package-level and does not have a containing object, it is simply placed into the file [Filename]Kt which in this case is JvmClassMappingKt . Here is the source of this extension property: @Suppress("UPPER_BOUND_VIOLATED") public val <T> KClass<T>.java: Class<T> @JvmName("getJavaClass") get() = (this as ClassBasedDeclarationContainer).jClass as Class<T> As you can see, the method's name is renamed on the JVM to getJavaClass . In your case, you can try: public <T> T proxy(KClass<T> kClass) { return (T) proxy(JvmClassM...

Constructors In Kotlin

Answer : Well init is not body of constructor. It is called after primary constructor with the context of primary constructor. As given in Official documentation: The primary constructor cannot contain any code. Initialization code can be placed in initializer blocks, which are prefixed with the init keyword: class Customer(name: String) { init { logger.info("Customer initialized with value ${name}") } } Note that parameters of the primary constructor can be used in the initializer blocks. They can also be used in property initializers declared in the class body: class Customer(name: String) { val customerKey = name.toUpperCase() } In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax: class Person(val firstName: String, val lastName: String, var age: Int) { // ... } As per your question you can add a constructor to accept one parameter like following: class Person(name: String, surn...

Coroutines: RunBlocking Vs CoroutineScope

Answer : I don't understand how coroutineScope and runBlocking are different here? coroutineScope looks like its blocking since it only gets to the last line when it is done. From the perspective of the code in the block, your understanding is correct. The difference between runBlocking and coroutineScope happens at a lower level: what's happening to the thread while the coroutine is blocked? runBlocking is not a suspend fun . The thread that called it remains inside it until the coroutine is complete. coroutineScope is a suspend fun . If your coroutine suspends, the coroutineScope function gets suspended as well. This allows the top-level function, a non-suspending function that created the coroutine, to continue executing on the same thread. The thread has "escaped" the coroutineScope block and is ready to do some other work. In your specific example: when your coroutineScope suspends, control returns to the implementation code inside runBlocking . This...

Android Get Current Timestamp?

Answer : The solution is : Long tsLong = System.currentTimeMillis()/1000; String ts = tsLong.toString(); From developers blog: System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch. The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important, such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you are using System.currentTimeMillis() , consider listening to the ACTION_TIME_TICK , ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED Intent broadcasts to find out when the time changes. 1320917972 is Unix timestamp using number of seconds since 00:00:00 UTC on January 1, 1970. You can use TimeUnit class for unit conversion - from System.currentTimeMillis() to s...

Android Vibrate Is Deprecated. How To Use VibrationEffect In Android>= API 26?

Answer : Amplitude is an int value. Its The strength of the vibration. This must be a value between 1 and 255, or DEFAULT_AMPLITUDE which is -1. You can use it as VibrationEffect.DEFAULT_AMPLITUDE More details here with kotlin private fun vibrate(){ val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE)) } else { vibrator.vibrate(200) } } You can use this for haptic feedback (vibration): view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); There are other constants available in HapticFeedbackConstants like VIRTUAL_KEY , KEYBOARD_TAP ...

Creating A New Instance Of A KClass

Answer : You can use the Java class to create new instance: MyClass::class.java.newInstance() In your case, Java reflection might be enough: you can use MyClass::class.java and create a new instance in the same way as you would with Java reflection (see @IngoKegel's answer). But in case there's more than one constructor and you really need to get the primary one (not the default no-arg one), use the primaryConstructor extension function of a KClass<T> . It is a part of Kotlin reflection, which is not shipped within kotlin-stdlib . To use it, you have to add kotlin-reflect as a dependency, e.g. a in Gradle project: dependencies { compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" } Assuming that there is ext.kotlin_version , otherwise replace $kotlin_version with the version you use. Then you will be able to use primaryConstructor , for example: fun <T : Any> construct(kClass: KClass<T>): T? { val ctor = kClass.primaryCo...

Accessing Kotlin Extension Functions From Java

Answer : All Kotlin functions declared in a file will be compiled by default to static methods in a class within the same package and with a name derived from the Kotlin source file (First letter capitalized and ".kt" extension replaced with the "Kt" suffix). Methods generated for extension functions will have an additional first parameter with the extension function receiver type. Applying it to the original question, Java compiler will see Kotlin source file with the name example.kt package com.test.extensions public fun MyModel.bar(): Int { /* actual code */ } as if the following Java class was declared package com.test.extensions class ExampleKt { public static int bar(MyModel receiver) { /* actual code */ } } As nothing happens with the extended class from the Java point of view, you can't just use dot-syntax to access such methods. But they are still callable as normal Java static methods: import com.test.extensions.ExampleKt; MyMod...

Android Architecture Components: Gradle Sync Error For Dependency Version

Answer : As @RedBassett mentions Support libraries depends on this lightweight import (runtime library) as explained at android developers documentation. This is, android.arch.lifecycle:runtime:1.0.0 is spreading up in the dependency tree as a result of an internal api (transitive) import so in my case I only had to include extensions library as "api" instead of "implementation" so that it will override its version to the highest (1.1.1). In conclusion, change implementation "android.arch.lifecycle:extensions:1.1.1" to api "android.arch.lifecycle:extensions:1.1.1" In your main build.gradle file allprojects { ... configurations { all { resolutionStrategy { force "android.arch.lifecycle:runtime:1.1.1" } } } } This will enforce version 1.1.1 Apparently support-v4 was causing the conflict. In the case of this question, the Gradle dependency task wasn...

Android With Kotlin - How To Use HttpUrlConnection

Answer : Here is a simplification of the question and answer. Why does this fail? val connection = HttpURLConnection() val data = connection.inputStream.bufferedReader().readText() // ... do something with "data" with error: Kotlin: Cannot access '': it is 'protected/ protected and package /' in 'HttpURLConnection' This fails because you are constructing a class that is not intended to directly be constructed. It is meant to be created by a factory, which is in the URL class openConnection() method. This is also not a direct port of the sample Java code in the original question. The most idiomatic way in Kotlin to open this connection and read the contents as a string would be: val connection = URL("http://www.android.com/").openConnection() as HttpURLConnection val data = connection.inputStream.bufferedReader().readText() This form will auto close everything when done reading the text or on an exception. If you...

Access Application Context In Companion Object In Kotlin

Answer : please see this go to link class MainApplication : Application() { init { instance = this } companion object { private var instance: MainApplication? = null fun applicationContext() : Context { return instance!!.applicationContext } } override fun onCreate() { super.onCreate() // initialize for any // Use ApplicationContext. // example: SharedPreferences etc... val context: Context = MainApplication.applicationContext() } } Actually I'm working inside an Android library and the class is abstract, so can't go with the already suggested solutions. However, I found way to do that. Creat a lateinit Context field inside companion object. abstract class MyClass { companion object { private lateinit var context: Context fun setContext(con: Context) { context=con } } } And then set it after the app has s...

Can Kotlin Data Class Have More Than One Constructor?

Answer : A Kotlin data class must have a primary constructor that defines at least one member. Other than that, you can add secondary constructors as explained in Classes and Inheritance - Secondary Constructors. For your class, and example secondary constructor: data class User(val name: String, val age: Int) { constructor(name: String): this(name, -1) { ... } } Notice that the secondary constructor must delegate to the primary constructor in its definition. Although many things common to secondary constructors can be solved by having default values for the parameters. In the case above, you could simplify to: data class User(val name: String, val age: Int = -1) If calling these from Java, you should read the Java interop - Java calling Kotlin documentation on how to generate overloads, and maybe sometimes the NoArg Compiler Plugin for other special cases. Yes, but each variable should be initialized, so you may set default arguments in your data class constructo...