How to use AndroidAnnotation #SharedPref with Kotlin - android

I'm trying to use AndroidAnnotations #SharefPref within kotlin, but Iget following error
org.androidannotations.annotations.sharedpreferences.Pref can only be used on an element that extends org.androidannotations.api.sharedpreferences.SharedPreferencesHelper
What am I doing wrong?
//Interface
#SharedPref(SharedPref.Scope.APPLICATION_DEFAULT)
open interface MyPreferences {
#DefaultInt(-1)
fun someIntValue():Int
}
//Fragment
#Pref
lateinit open var sharedPref:CongressPreferences_
//usage within fragment
val get: Int = sharedPref.selectedEventId().get()

This is due to a bug in the Kotlin annotation processor.
To fix this, you must add correctErrorTypes = true to your kapt block.
kapt {
correctErrorTypes = true
}
Also make sure you are using the latest Kotlin version (as of this moment: 1.1.3).

I just wanna extend on #WonderCsabo 's answer.
His answer almost saved me, but not fully.
After adding this to my app label build gradle.
kapt {
correctErrorTypes = true
}
I wasn't able to run my app.
Then I closed my android studio and then run Android studio again as administrator.
Voila! it works like charm.
Thank you #WonderCsabo

Related

DataBinderMapperImpl not adding mapper for module

I'm facing exactly the same problem described here: DataBinding V2 Crashes in multi module android Projects
But there is not any answer on that question.
The problem is that the DataBinderMapperImpl generated class is not being correctly generated:
public class DataBinderMapperImpl extends MergedDataBinderMapper {
DataBinderMapperImpl() {
addMapper(new com.xxx.appmodule.DataBinderMapperImpl());
}
}
If I modify that class and (manually) add a new line for the missing mapper impl:
addMapper(new com.xxx.appmodule.DataBinderMapperImpl());
addMapper(new com.xxx.missingmodule.DataBinderMapperImpl());
Then everything works as expected, but obviously this is not a solution.
Tried with both:
buildFeatures {
dataBinding true
}
// and
dataBinding {
enabled = true
}
But the result is the same.
The most annoying thing is that this behaviour is random. Sometimes the compiler/plugin/??? works ok and the class is correctly generated.
This started to happen just after migrating the project to AndroidX.
Any help would be appreciated!
UPDATE:
This seems to be related to the kotlin-kapt plugin. Currently we are applying that plugin in both module and app build.gradle. If I remove the apply plugin: 'kotlin-kapt' from the module, then the data binding mapper is added in the app's module DataBinderMapperImpl:
#Override
public List<DataBinderMapper> collectDependencies() {
ArrayList<DataBinderMapper> result = new ArrayList<DataBinderMapper>(2);
result.add(new androidx.databinding.library.baseAdapters.DataBinderMapperImpl());
result.add(new com.xxx.missingmodule.DataBinderMapperImpl());
return result;
}
But this has no sense at all for me. What am I missing?

Cant set buildFeatures databinding with Kotlin DSL

I am migrating to Kotlin dsl and I can't set buildFeatures property databinding any more. It is missing from AppExtension class. It is happening in dynamic feature module
Any suggestions?
Before in Groovy worked
android {
buildFeatures {
dataBinding = true
}
}
Kotlin is not working either the same syntax or
buildFeatures.dataBinding = true
Attaching some screenshots.
The error is
Unresolved reference: dataBinding
After submitting a ticket to Google the answer is to use
https://issuetracker.google.com/issues/193452960
android.dataBinding.isEnabled = true
Based on the dev reply marking it as deprecated is a bug and should not be thee case in kts.
From the ticket:
Sorry for the mixed messages about build features, we realized that it made more sense to put the enable flag for features next to the feature itself. The plan is that the supported path will be:android.dataBinding.isEnabled = true
Which works today in kts, but is currently incorrectly marked as deprecated.
You could try to upgrade your AGP.

Set gradle.ext in settings.gradle.kts with Gradle Kotlin DSL

Here's code snippet from google/exoplayer - which is written in Groovy buildscript.
// settings.gradle
gradle.ext.exoplayerRoot = 'path/to/exoplayer'
gradle.ext.exoplayerModulePrefix = 'exoplayer-'
apply from: new File(gradle.ext.exoplayerRoot, 'core_settings.gradle')
How can I achieve this using Kotlin DSL?
I couldn't find any useful resources or documents. Any help would be appreciated.
Found a solution after digging a while.
In Groovy, there's dynamic implementation of traits - So even if class A does not implement interface B in the class definition, it may implement it later in the future.
I didn't see Gradle internals so I can't properly explain this, but it seems to work. Hope this helps.
if (gradle is ExtensionAware) {
val extension = gradle as ExtensionAware
extension.extra["exoplayerRoot"] = "path/to/exoplayer"
extension.extra["exoplayerModulePrefix"] = "exoplayer-"
apply(from = File(extension.extra["exoplayerRoot"].toString(), "core_settings.gradle"))
}
For those who uses ExoPlayer, I created an issue for requesting some documents for Kotlin DSL users.

Note: Failed to read get kotlin metadata for [Ljava.lang.Object;#79d6c4df

I keep getting this error.
I am working on a project and in the middle of development, I decided to migrate to Android X.
I get the error below:
Note: Failed to read get kotlin metadata for [Ljava.lang.Object;#79d6c4df
There is the same error in a entity file and 4 of the same error in the respective DAO as well.
Here is the code of DAO:
#Dao
public interface FlockDao{
#Query("SELECT * FROM flock_table")
LiveData<List<Flock>> getAllFlocks();
#Query("SELECT * FROM flock_table WHERE fid IN (:flockIds) LIMIT 1")
Flock loadFlockById(int[] flockIds);
#Insert
void insert(Flock flock);
#Update
void update(Flock flock);
#Delete
void delete(Flock flock);
}
And my entity is:
#Entity
public class Flock{
#PrimaryKey(autoGenerate = true)
private int fid;
#ColumnInfo(name = "user_id")
private int uid;
#ColumnInfo(name = "name")
private String name;
#ColumnInfo(name = "capacity")
private int capacity;
#ColumnInfo(name = "type")
private String type;
#ColumnInfo(name = "arrived")
private Date arrived;
.....rest of the code is omitted, there are constructor, setters and getters
}
I updated my Room depency to 2.1.0-alpha05 and got the same problem. Returning to 2.1.0-alpha04 solved mine.
implementation 'androidx.room:room-runtime:2.1.0-alpha04'
annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha04'
UPDATE
If you really want to use Room version 2.1.0-alpha05, add the following depency to your project repository:
maven { url 'https://kotlin.bintray.com/kotlinx/' }
Reference: AndroidX Room Release Notes
UPDATE
I tried 2.1.0-alpha06.
implementation 'androidx.room:room-runtime:2.1.0-alpha06'
annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha06'
Then I add the depency to my project repository,
maven { url 'https://kotlin.bintray.com/kotlinx/' }
There was na error but it compiled. I tested my app in real device for weeks and there wasn’t any issue running my app. My Room database is working fine.
I solved this issue by downgrading to:
implementation 'androidx.room:room-runtime:2.1.0-alpha04'
annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha04'
Solved!
//Downgraded to alpha04.
implementation 'androidx.room:room-runtime:2.1.0-alpha04'
annotationProcessor 'androidx.room:room-compiler:2.1.0-alpha04'
// Other dependencies are..
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0-alpha03'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.1.0-alpha03'
implementation 'androidx.lifecycle:lifecycle-livedata:2.1.0-alpha03'
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.1.0-alpha03'
// Removed this from project level gradle.
maven { url "https://kotlin.bintray.com/kotlinx/" }
Don't forget to Clean & Rebuild the project after these changes
Like most errors that have something to do with Room, the error message that pops up the most is most unlikely to be your problem. For me it helped to raise the max Error count by adding :
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xmaxerrs" << "1000"
}
}
and then executing the gradle task:
:app compileDebugJavaWithJavac
Then you will get a large list of errors, in your case the
Note: Failed to read get kotlin metadata for [Ljava.lang.Object;#79d6c4df
But somewhere in that list are your real errors like a wrong query or something like that.
Fix those errors and rebuild the project, that works most of the time, but sometimes you have to invalidate the cache and restart Android Studio.
Invalidate caches and restart solved my problem. My room version is 2.1.0-alpha06 and I have also add the following dependency to my project repository:
maven { url 'https://kotlin.bintray.com/kotlinx/' }
I got the same error, I updated the room libraries, but issue not fixed,
then I did below steps, ... after that problem solved,
Step 1: Check #DataBase class in your project and check all tables (entities) are inserted
Step 2: Increment version number
Step 3: Add ".fallbackToDestructiveMigration()" before .build().
Don't forget to Clean & Rebuild the project after these changes
As I was typing this answer, I was notified of 2.1.0-alpha07. It resolved all errors. Going back to 2.1.0-alpha06 broke the build again.
It turns out the new version resolved the errors for me.
Before trying to resolve the error, try updating Android Studio first. After updating Gradle, all dependencies, and AS from 3.3.2 to 3.4, I found errors I haven't encountered before, like
error: Room cannot pick a constructor since multiple constructors are suitable. Try to annotate unwanted constructors with #Ignore.
error: Cannot find setter for field.
There are multiple good constructors and Room will pick the no-arg constructor. You can use the #Ignore annotation to eliminate unwanted constructors.
error: Not sure how to convert a Cursor to this method's return type.
Once I fixed them, the build was successful and the app ran. I didn't need to add any additional maven repos mentioned in the accepted answer.
Adding import androidx.room.Dao; and then re-importing it did the trick for me.
I solved by adding this to build.gradle (Module)
androidTestImplementation "androidx.arch.core:coretesting:$rootProject.archLifecycleVersion"
In my build.gradle(Project)
ext {
roomVersion = '2.1.0-alpha06'
archLifecycleVersion = '2.0.0'
}
Just change room_version in your gradle_module file in dependency block and change other room associated libraries you need. Use https://developer.android.com/jetpack/androidx/releases/room#2.2.0-alpha01 as an example. Try to use latest stable version of room.
I have the same error and i used version 2.1.x-alpha
and after updated to 2.2.3
the new version reported the error correctly and it was that one of my entities didn't have primary key
I came across the same problem and fixed it by override the equals & hashCode methods of the object.
A possible solution for your case:
#Override
public int hashCode() { return (27 * fid + (name!= null ? name.hashCode() : 0)); }
And
#Override
public boolean equals(#Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Flock)) return false;
Flock flock = (Flock) obj;
if(fid != flock.fid) return false;
return name != null ? name.equals(flock.name) : flock.name == null;
}
you will also need find a solution for the Date usage in Room, Room doesn't have a build in solution for a Date variable.

Timber Not Logging in Kotlin Android

Timber is a great library for logging in Android. In Kotlin classes though, doesn't output anything. How can I fix this?
MainActivity.kt code:
Timber.e("Timber Log 1")
Log.e("MainActivity", "Log 1")
Gradle:
I've tried the regular Java Timber:
implementation 'com.jakewharton.timber:timber:4.7.1'
And this Kotlin specific wrapper:
implementation 'com.github.ajalt:timberkt:1.5.1'
Same result. No output with either. Only from the Log.e()
The first step of Timber is to plant the tree as mentioned in docs
Behavior is added through Tree instances. You can install an instance
by calling Timber.plant. Installation of Trees should be done as early
as possible. The onCreate of your application is the most logical
choice.
And use the debugTree
The DebugTree implementation will automatically figure out from which
class it's being called and use that class name as its tag. Since the
tags vary
If you don't do this then you will have no logs entry and do this as soon as possible, like in oncreate or better inside application class so do this
Timber.plant(Timber.DebugTree());
I have faced same problem, using Kotlin and Android studio 3.6
Follow these steps:
Add the following in build.gradle(Module: App)
implementation 'com.jakewharton.timber:timber:4.7.1'
Initialize Timber in Application Class:
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
if(BuildConfig.DEBUG){
Timber.plant(Timber.DebugTree())
}
}
}
Add the Application class(MyApp) to the Manifest (AndroidManifest.xml)
<application
android:name=".MyApp"
Now you can use Timber: Timber.i("Timber logs")
Also can use custom tags if you wish: Timber.tag("Yo").I("used custom tag for logs")
In my case it was wrong BuildConfig import
import org.koin.android.BuildConfig
but my app has
import com.company.example.BuildConfig
Probably late to the party but my problem was the my phone was set to "Charge only" and not "file transfer". Apparently I was allowed to build and run, but logs were blocked
EDIT Another solution:
Check your RUN tab in the bottom of Android Studio. Sometimes the logs get output to there instead
For me it started showing up when I commented the Debug check
// if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
// }
I don't know why this is working because the build varient is selected to debug only.

Categories

Resources