it's my first time diving in with protobuf and jetpack's DataStore but I've encountered an issue which is quite confusing.
I've created my .proto file in src/main/java/proto, it's really simple:
syntax = "proto3";
option java_package = "com.test.appname.proto";
option java_multiple_files = true;
message WalkInfo {
float distance = 1;
bool run = 2;
}
Then I've written in kotlin a serializer class for some data in my app.
object WalkInfoSerializer : Serializer<Walker.WalkInfo>{
override val defaultValue: Walker.WalkInfo
get() = WalkInfo.getDefaultInstance()
override fun readFrom(input: InputStream): Walker.WalkInfo {
try {
return WalkInfo.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(t: Walker.WalkInfo, output: OutputStream) {
t.writeTo(output)
}
}
I've also set up my build.gradle file like this:
plugins {
id 'com.android.application'
id 'kotlin-android'
id "com.google.protobuf" version "0.8.14"
}
...
dependencies {
...
//DataStore
implementation "androidx.datastore:datastore:1.0.0-alpha05"
implementation 'com.google.protobuf:protobuf-javalite:3.14.0'
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.10.0"
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
Everything works fine, the classes seem to be generated correctly and they even pop up in android studio's autocomplete.
The problem is that I can't get the project to compile as I can't seem to find a way to resolve the "Unresolved Reference" for the methods generated (like getDefaultInstance(), parseFrom(), writeTo()
Even by writing the full class path it won't work.
Am I missing something? I've tried to play around with build.gradle and the proto file with some settings I found in their documentation but I still couldn't get it to work
Thank you!
Went to sleep, woke up, and knew the answer to my problems.
Dumb brain managed to do 1 + 1 during the night.
I realized that if the proto classes are being generated, I should not be defining them myself in kotlin code.
I had a WalkInfo message that generated a WalkInfo class, but I also had a WalkInfo class already with some methods in it. This is what was confusing the compiler.
After further research I realized that classes generated by proto are not even meant to be extended, they are supposed to be just data containers.
What I ended up doing is renaming my message to WalkInfoStorage while also keeping my WalkInfo kotlin class, I'll then be handling generating WalkInfo instances from the serialized data
I have an Android app using Gradle with Kotlin DSL. I'm adding Firebase Performance Monitoring, but I would like for it to be enabled only for a specific build type.
I've been following the instructions provided at Firebase - Disable Firebase Performance Monitoring. Unfortunately the provided snippets are in Groovy.
I've tried to get a reference to the Firebase Performance Monitoring extension in my app level Gradle script by doing the following:
plugins {
...
id("com.google.firebase.firebase-perf")
kotlin("android")
kotlin("android.extensions")
kotlin("kapt")
}
buildTypes {
getByName(BuildTypes.DEBUG) {
configure<com.google.firebase.perf.plugin.FirebasePerfExtension> {
setInstrumentationEnabled(false)
}
}
...
}
...
dependencies {
val firebaseVersion = "17.2.1"
implementation("com.google.firebase:firebase-core:$firebaseVersion")
implementation("com.google.firebase:firebase-analytics:$firebaseVersion")
implementation("com.google.firebase:firebase-perf:19.0.5")
}
Android Studio doesn't see any problem in this and auto-completes FirebasePerfExtension.
Unfortunately upon running a Gradle sync I get the following:
Extension of type 'FirebasePerfExtension' does not exist.
Currently registered extension types: [ExtraPropertiesExtension, DefaultArtifactPublicationSet, ReportingExtension, SourceSetContainer, JavaPluginExtension, NamedDomainObjectContainer<BaseVariantOutput>, BaseAppModuleExtension, CrashlyticsExtension, KotlinAndroidProjectExtension, KotlinTestsRegistry, AndroidExtensionsExtension, KaptExtension]
There's no plugin extension related to Firebase Performance Monitoring.
This is in my project level build.gradle file dependencies block:
classpath("com.google.firebase:perf-plugin:1.3.1")
Any help is appreciated!
Update 1
As recommended on the Gradle - Migrating build logic from Groovy to Kotlin guide at "Knowing what plugin-provided extensions are available" I've ran the kotlinDslAccessorsReport task. None of the resulting extensions seems to be related to Firebase.
Had the same issue and was going to apply from groovy file, but seems i found the solution in here: https://docs.gradle.org/5.0/userguide/kotlin_dsl.html#sec:interoperability
withGroovyBuilder {
"FirebasePerformance" {
invokeMethod("setInstrumentationEnabled", false)
}
}
We used this answer, util we discovered a better working way in the team
check(this is ExtensionAware)
configure<com.google.firebase.perf.plugin.FirebasePerfExtension> { setInstrumentationEnabled(false) }
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
I have some code snippets below when I use android databinding framework with ViewStub.
ItemPostBinding binding=ItemPostBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
final Post post = mDataset.get(position);
binding.stub.getViewStub().setLayoutResource(App.getPostExtensionManager().getLayout(post.getExtension()));
I kown binding.stub will be replaced with ViewStubProxy when codes compiled. But how could I ask Android Studio to ignore the error here before compiling?
(The error is Android Studio cannot resolve getViewStub() method from class ViewStub)
UPDATE 1
I don't know if it was due to my old approach of using android data-binding framework.
classpath 'com.android.databinding:dataBinder:1.0-rc4' // project build.gradle
apply plugin: 'com.android.databinding' // module build.gradle
But with the new method mentioned in the official data-binding guide, all you need to do is adding the settings below in your module's build.gradle file.
android {
....
dataBinding {
enabled = true
}
}
And the error inspections mentioned above is gone, you can even directly use binding.stub without any problem.
binding.stub.setLayoutResource(...)
binding.stub.inflate()
...
UPDATE 2
You can use binding.stub.someViewStubMethod() directly but it will fail while compiling. You still need to use binding.stub.getViewStub().someMethod(). However, just recently the error inspections is gone somehow no matter which method you add data-binding into your project by.
You are not suppose to call getViewStub method this way. binding.stub is already the ViewStub which you put in your layout item_post. You should call binding.stub.setLayoutResource()
Android Studio can't recognize ViewStubProxy correctly. Just cast it before manipulate.
import android.databinding.ViewStubProxy;
...
ViewStubProxy viewStubProxy = (ViewStubProxy)(Object)mBinding.viewStub;
if (!viewStubProxy.isInflated()) {
viewStubProxy.getViewStub().inflate();
}
Error is gone :)
I want to use Android Data Binding and has configured according to the official document.
the error message is :
error: cannot find symbol import net.juude.droidviews.BR;
the top level build.gradle file is:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:1.3.0-beta2"
classpath 'me.tatarka:gradle-retrolambda:3.0.1'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
classpath "com.android.databinding:dataBinder:1.0-rc0"
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
and the build.gradle file in app module is
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'com.android.databinding'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
lintOptions {
abortOnError false
}
defaultConfig {
applicationId "net.juude.droidviews"
minSdkVersion 15
targetSdkVersion 22
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
retrolambda {
println("JAVA_HOME: " + System.getenv("JAVA_HOME"))
println("JAVA7_HOME: " + System.getenv("JAVA7_HOME"))
println("JAVA8_HOME: " + System.getenv("JAVA8_HOME"))
javaVersion JavaVersion.VERSION_1_7
}
}
dependencies {
compile project(':ptr-lib-debug')
compile project(':library')
compile 'com.android.support:support-v4:22.1.0'
compile 'com.mcxiaoke.volley:library:1.0.+'
compile files('libs/droidmocks.jar')
compile 'com.android.support:support-annotations:22.1.1'
compile 'com.facebook.fresco:fresco:0.5.0'
compile 'com.android.support:recyclerview-v7:22.1.1'
compile 'io.reactivex:rxandroid:0.24.0'
compile 'io.reactivex:rxjava:1.0.6'
compile 'com.google.dagger:dagger:2.0'
apt 'com.google.dagger:dagger-compiler:2.0'
}
the layout file is
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type=" net.juude.droidviews.databinding.User" />
</data>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.mName}"/>
<TextView
android:id="#+id/user_sex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.sex}"/>
</LinearLayout>
</layout>
the fragment is
package net.juude.droidviews.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.juude.droidviews.BR;
import net.juude.droidviews.R;
/**
* Created by juude on 15-6-9.
*/
public class DataBindingFragment extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewDataBinding dataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_data_binding, container, false);
//dataBinding.setVariable(BR.)
User user = new User();
user.setSex("男");
user.setName("Juude");
dataBinding.setVariable(BR.user, user);
return dataBinding.getRoot();
}
}
since I did not get syntax error in Android Studio, I can assume that the Android Studio can recognize the BR class;
But when I compile the project, It tells me that
error:cannot find symbol class BR.
so I want to know what should I do to make it generate the right BR.java file?
In case someone still has this problem. I solved this by invalidating the cache in Android Studio. And I'm using Android Studio 2 with API 23
File > Invalidate Caches/Restart
It is a problem caused by android-apt plugin. It ignores the provided dependency that data binding plugin adds.
https://bitbucket.org/hvisser/android-apt/issue/38/android-apt-breaks-brand-new-data-binding#comment-18504545
You can work around it by adding:
apt 'com.android.databinding:compiler:1.0-rc0 to your gradle file.
If you are using Kotlin, try applying the following plugin to your app build.gradle file:
apply plugin: 'kotlin-kapt'
Clean your project and build it again. This solved the issue for me.
I find the cause of the problem in my case. I find in the import statements of my Data Object class contains:
import static android.databinding.tool.util.GenerationalClassUtil.ExtensionFilter.BR;
The problem gets solved after I removed that. Android Studio somehow resolved BR class wrongly for me.
The Bindable annotation generates an entry in the BR class file during compilation. The BR class file will be generated in the module package.
#Bindable
public String getFirstName() {
return this.firstName;
}
I ran into this issue too. The problem was that I changed the class name and didn't update the values in the XML file. This includes the variable names and where they are accessed in the xml file.
For my case the issue was caused by
"error: variable MyVariable was already defined in class MyModel"
The annoying thing was Android Studio gradle build did not display this error at the bottom. I had to comment each databinding error > Rebuild Project until I reach the error. Lesson learnt was to scan through each error from bottom to top and notice anything you may have changed recently.
I too got the same error message, but my root cause was different from what has been shared here.
In my case the issue was that after I resolved a merge conflict, I had by mistake left an extra #Override annotation on a method. Thus the JVM preprocessor failed and then also the data binding classes were not generated.
The irritating part for me was that I was unable to see any error message related to this, or it was hard to spot among all the other compiler errors. And Android Studio does not show the extra annotation as an error either. So in case someone else struggles with the same error, check that you don't haven an error in some annotation that prevents the APT preprocessor from kicking in.
You need to add this to your gradle.properties file
android.databinding.enableV2=true
From developer.android.com
you might get multiple errors reporting that the binding classes aren't found. The new data binding compiler prevents these errors by generating the binding classes before the managed compiler builds your app.
Just restarting Android Studio, without invalidating cache, did the trick for me (I'm using version 2.2.3).
I had this plus 29 other errors suddenly crop up from one moment to the next. I tried clean, rebuild, invalidate caches / restart and no luck. In the end I removed changes I had made and redid them one by one. Found that I had #Injected a service in the wrong class. Once I removed that all 30 errors were gone. The errors gave no clue to what I had done wrong.
If you use Android Studio 2.3 release and your project configuration is as follow:
Gradle version: 3.3
Android plugin version:2.3.0
Compile sdk Version:23+
build tools Version:25+
All need to do is add
dataBinding{enabled=true}
to build.gradle, then sync gradle file.
For me it helped to run ./gradlew clean build in the project folder. It showed an error which android studio didn't.
Generally BR class Generate automatically when you Rebuild your project and I have resolved the problem using this technique Still have issue you can try another solution.
You need to double-check the following steps:
GradleFile:
dataBinding {enabled = true}
Your class Model.
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.databinding.library.baseAdapters.BR
class User2(
private var firstName: String,
private var lastName: String
) : BaseObservable() {
fun setFirstName(firstName: String) {
this.firstName = firstName
notifyPropertyChanged(BR.firstName)
}
#Bindable
fun getFirstName(): String {
return this.firstName
}
}
If you are using Dagger 2, the problem may be caused by dagger's components. Although two libraries are not related, in my case, fixing errors in Dagger reported in the compiler makes the BR class properly appear again.
BR gets generated during compilation, Build -> Rebuild project should do the trick. But for me it failed with error:
e:/home/xx/File.kt: (24, 46): Expecting an element because on that line I had an incompleted BR.. Just commenting or adding anything after . and rebuilding solved it.
Just follow the steps below,
1.Extend your class with BaseObservable class
2.Add #Bindable annotation to each getter methods.
3.Rebuild the project.
Now you'll be able to access BR
In my case, I tried just running the project and it fixed the issue.
Add dependency
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
Then sync project. Even if not works, invalidate cache and restart then clean & rebuild project.
In my case i haven't provided #PrimaryKey annotation on one of the entity and it was really difficult to find this error as in logs there are no clue to find it. so be sure to give your Entity a primary key, else this error occurs.
Check your room database related file, because of that class gradle build get failed, and will not get idea actually. issue is in room classes.
what ever androidx.databinding.library.baseAdapters.BR error your getting those file is not generating because of room database class have some syntax error