CoordinatorLayout.DefaultBehaviour deprecated, no other option - android

So according to android documentation, defaultBehaviour is deprecated and AttachedBehaviour should be used instead.
However:
does not "exist" in android. I always receive the Annotation type expected error.
My import is:
import androidx.coordinatorlayout.widget.CoordinatorLayout;
Am I using the wrong import?

AttachedBehavior is an interface, not an annotation.
Therefore your CustomLinearLayout must implement AttachedBehavior and override the getBehavior() method to return an instance of your MoveUpwardBehavior class.

Related

Non-SDK interface: Is using getter disallowed?

as of Android 11 using mParent from Activity.java is on the list of greylisted (https://developer.android.com/about/versions/11/test-changes aka banned) things. The relevant line from the article is below:
Landroid/app/Activity;->mParent:Landroid/app/Activity; # Use androidx.fragment.app.Fragment and androidx.fragment.app.FragmentManager instead.
However, does this mean I cannot use the corresponding getter, Activity.getParent() ? I imagine the getter would be fine, just not changing the variable, because if the getter was banned then they would list that explicitly (as they list other getters) but the comment to use Fragment or FragmentManager is throwing me off.
getParent() is a public method on Activity. You do not need reflection to use it, and you can call it on every Android version.

ArgumentMatchers.any must not be null

I am trying to test ViewModel to make sure livedata gets updated correctly. However when using ArgumentMatchers.any() it fails with IllegalStateException saying:
ArgumentMatchers.any(mViewModel.CountSubscriber::class.java) must not
be null
#Test
fun emitValueIfCountIs7() {
doAnswer { invocation: InvocationOnMock ->
val subscriber: mViewModel.CountSubscriber = invocation.getArgument(0)
subscriber.onNext(7)
null
}.`when`(countUseCase).execute(
ArgumentMatchers.any(mViewModel.CountSubscriber::class.java),
ArgumentMatchers.any(Parameters::class.java)
)
// When
mViewModel.getCount()
// Verify
assert(mViewModel.countResponse.value != null)
}
I am using Kotlin and have the following dependencies:
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:2.23.4"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
Here are my imports:
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.doAnswer
import io.reactivex.Observable
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.invocation.InvocationOnMock
Strange thing is that it used to work before, and I don't know what has happened that could affect this.
Getting matchers to work with Kotlin can be a problem.
If you have a method written in kotlin that does not take a nullable parameter, then we cannot match with it using Mockito.any().
This is because it can return void and this is not assignable to a non-nullable parameter.
If the method being matched is written in Java, then I think that it will work as all Java objects are implicitly nullable.
One possible solution would be to use a library like mockito-kotlin
But you can solve this issue easily with a few lines of code yourself.
If you need typed any(type: Class)
private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
OR
You can use this matcher instead of Matchers.any() :
object MockitoHelper {
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
#Suppress("UNCHECKED_CAST")
fun <T> uninitialized(): T = null as T
}
and use MockitoHelper.anyObject() instead of any() in your kotlin tests.
You can find more information in this post: Using Mockito with Kotlin
There is a discussion about possible solutions in this post :
Is it possible to use Mockito in Kotlin?
The correct solution is mentioned in the comment section of the question by #Ana Koridze. Yes, if you are using Koltin + mockitoKotlin. Make sure you are using the following import:
1 - Using the Mockito-kotlin:
import org.mockito.kotlin.any from Mockito-kotlin
instead of
import org.mockito.Mockito.any
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
2 - Or if you are using older mockito kotlin version original created by nhaarman before the intergation
import com.nhaarman.mockitokotlin2.any from nhaaram's Mockito-kotlin instead of import org.mockito.Mockito.any
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin2_version"
BTW, if you are using Android Studio or IntelliJ IDEA. the any() from mockitokotlin library should be italic by default style/color scheme.
Notice the any() at the end of line. This is from mockitokotlin
And here is the any() from mockito
Thanks #Sattar for the recommended edit.
mockito-kotlin has added support for nullable args with anyOrNull()
`when`(myMock.doesThis(any(), anyOrNull())).thenReturn(someObject)
use Mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
this will use any that works for kotlin as this is a wrapper lib for Mockito but for kotlin
This is what worked for me,
either replaced all generic any()s , with a specific anyTYPE(), i.e anyInt(), anyList() etc from core lib org.mockito:mockito-core and it fixes the (nullability)issue, it seems the specific definitions with type can handle null. this option does not require you to import any extra lib
or
if you really need to use the generic type any() , add this official Mckito extension lib https://github.com/mockito/mockito-kotlin and make sure you use the any() from this lib (by making sure your imports has this in it import org.mockito.kotlin.any)
I suggest to start using MockK lib https://github.com/mockk/mockk instead of Mockito as it is a Mock library for Kotlin = MockK)
however, if you feel lazy to switch right now or maybe dealing with legacy tests (as in my case :), this should fix your issue too.
For me all solutions above were not enough - in addition to that I had to mark the called method as an 'open' method.
According to this:
https://github.com/mockito/mockito-kotlin/wiki/Parameter-specified-as-non-null-is-null
The method is final and Mockito couldn't mock it so I had to add 'open'.
I wrote a simple wrapper function around Mockito's any() and got rid of the warning.
private fun <T> any() : T {
return org.mockito.ArgumentMatchers.any()
}
I am still pretty green at Kotlin though, so I am not sure whether there may be some unwanted side effects. I put this answer out there in case it helps anyone or someone gives me feedback.

How to suppress spellcheck on a string constant in Android Kotlin?

Android Lint picks up the string constant in this code sample as a spelling error on "dWQGSCDx". According to the docs I should use #SupressLint("Typos") to suppress it but that doesn't achieve that. I see others have suggested using #SuppressWarnings but that is not working either.
/**
* Constants.kt
*/
import android.annotation.SuppressLint
#SuppressLint("Typos")
#SuppressWarnings("SpellCheckingInspection")
const val SOME_STRING_VALUE = "...dWQGSCDx..."
Note this is a file-scoped global constant, it is not inside a class so an annotation cannot be placed on a containing class.
How do I suppress spell-checking of this constant definition without disabling spellcheck entirely and without adding the "mispelt" text to the dictionary?
In Kotlin you can suppress this warning using #Suppress instead of #SuppressWarnings with the following annotation
#Suppress("SpellCheckingInspection")

Kotlin inheritnce - No value passed for parameter context

I'm trying to build an AccountAuthenticator class with kotlin for android. But when trying to implement the AbstractAccountAuthenticator class I get the following exception at compile:
No value passed for parameter context
I'm not entirely sure what it means and can't find anything on how to solve it.
Here is the relevant code:
import android.accounts.AbstractAccountAuthenticator
import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.os.Bundle
class AccountAuthenticator: AbstractAccountAuthenticator() {}
Does anyone know what this means, why, and how to fix it?
AbstractAccountAuthenticator's constructor takes a Context context parameter. So you'll have to pass a Context to it somehow, for example, your AccountAuthenticator could also have a Context parameter:
class AccountAuthenticator(context: Context): AbstractAccountAuthenticator(context) {}
I don't know much about Kotlin but AbstractAccountAuthenticator constructor takes a Context see here.
So I guess you have to implement this constructor and other related abstract methods.

Cant inject null value into class

I have a fragment that I want to reuse. Its functionality is the same, only the layout changes
I am using roboguice to inject views by id into the variables
I added this view for example:
#Nullable
#InjectView(R.id.edtEventLocationAddress)
private EditText edtEventLocationAddress;
now this view may or may not be present in the given layout i provided in the onCreateView method
this is why i put #Nullable on it
however, when I run the app, with the layout that does not have this view, I get
java.lang.NullPointerException: Can't inject null value into class
com.myapp.CreateEventPageFragment.edtEventLocationAddress when field is not #Nullable
What do I need to do to make roboguice allow me to reuse fragments, and only change their view ?
A late answer but just in case anyone else stumbles on this.
You are probably using android.support.annotation.Nullable or a similar annotation that has #Retention(RetentionPolicy.CLASS) (or RetentionPolicy.SOURCE). However, you need to use a #Nullable annotation that is retained at runtime for RoboGuice to find it. E.g. this one:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target({ElementType.FIELD, ElementType.METHOD,
ElementType.PARAMETER,
ElementType.LOCAL_VARIABLE})
#Retention(RetentionPolicy.RUNTIME)
public #interface Nullable {}
Import javax.annotation.Nullable instead of android.support.annotation.Nullable as it has runtime retention policy (see Michael.F answer).
Another possibility (which is how I ended up on this question) is that you have a typo in your XML file or in the Inject command, and it's trying to inject null because it didn't actually find the ID you specified.

Categories

Resources