Why does kotlin change method invocation by variable name - android

If I write in Android Studio in a kotlin file getPackageManager this is automatically changed to "packageManager" in cursive, why does this happen and why should somebody think that this is straightforward to understand?

If I write in Android Studio in a kotlin file getPackageManager this is automatically changed to "packageManager" in cursive, why does this happen
getPackageManager() is a method written in Java. By convention, a method starting with get in Java is considered a field accessor. In Kotlin fields are accessed through properties. When inter-opting with Java, Kotlin automatically converts the Java way of accessing properties with the Kotlin way. This makes your code consistently "Kotliny" even if you're accessing Java classes.
Why should somebody think that this is straightforward to understand?
Because - like the syntax in the Kotlin language itself - once you know how it works, it's straightforward to understand. This goes for most things one learns. Why would someone think this is not straightforward to understand?
So, it means you could understand the cursive stuff like an alias? because normally what you write in a file is something that exists, if you write getPackageManager this exists somewhere, if you write the name of a variable this exists somewhere, but in this case packageManager doesn't really exist
Well, it does exist because the compiler makes it exist, otherwise it wouldn't compile, would it? It's just syntactic sugar. You see packageManager (so that - again - your code looks more like Kotlin). Meanwhile the compiler sees getPackageManager(). Either way it refers to the same thing.
Hope that helps!

By default all the variables are private and their getter and setter are generated by the compilers, when you pick some value it is changed to getter or when you assign value it is changed to setter call by compiler.
class Obj(var variable = "Default Value")
val obj = Obj()
obj.variable // same as obj.getVariable()
obj.variable = "Hello" // same as obj.setVariable("Hello")
Reference: https://kotlinlang.org/docs/reference/java-interop.html#getters-and-setters

Related

Android Annotation Code Generation - Android Classes

When starting to build my first code generation annotation, I've found I can't generate Android classes, such as SharedPreferences, since I start with a Java Library module in order to extend AbstractProcessor.
I'm using kotlinpoet to generate my class, but need to create a property that is of type SharedPreferences.Editor which doesn't seem to be supported. I'm trying to something like the following:
val editorProperty = PropertySpec.builder("editor", android.content.SharedPreferences.Editor)
but this fails since the android package is not available. Does anyone know a workaround for this or is it just not possible?
You can simply use
PropertySpec.builder("editor",ClassName("android.content", "SharedPreferences.Editor"))
as kotlin poet doc says - Type names are dumb identifiers only and do not model the values they name.

Pass JNIEnv or Context from Java to Go

I've successfully written a go mobile library and used it from an Android Java app.
I've also successfully called a c function from JNI. This one has the JNIEnv pointer.
I'd like to pass the context/JNIEnv from Java to Go.
Here's where it seems to get complicated:
Go Mobile does not seem to use JNIEnv at all.
LoadJNI.java does have a context object and claims to pass it to the Go side. But there it isn't visible.
I've been able to include jni.h using the "C" directive
I can transfer the JNIEnv from JNI/C or store it there as a global variable but that's an ugly kludge.
https://github.com/golang/go/issues/16876 talks about a proposal to do reverse binding but it's unclear what the status is.
https://godoc.org/golang.org/x/mobile/cmd/gobind also talks about it but the following code snippet
import "Java/java/lang/System"
t := System.CurrentTimeMillis()
returns
cannot find package "Java/java/lang/System" in any of:
/usr/local/go/src/Java/java/lang/System (from $GOROOT)
/Users/----/go/src/Java/java/lang/System (from $GOPATH)
In C I solved it with a compiler directive: #cgo CFLAGS: -I...
But I'm not sure how to do it for Java
In short, I'm now stuck and would appreciate help. Ideally, I'd just like to pass the object as a parameter, if possible. However, I'd settle for any reverse binding to call Java from Go.
I hate to answer my own question, but I'd hate someone to go through this as well too. I'll update this answer as I go along.
Basic Setup
Edit build.gradle and add GOPATH and GO to gobind (additions in bold):
gobind {
pkg = ".../reverse/reverse"
GOPATH = "/Users/johndoe/go"
GO = "/usr/local/go/bin"
}
How to develop
Start from the reverse example. Get it to compile and run.
Make one modification and recompile.
Missing gobind
It turns out the installation process neglected to build gobind. Run go install golang.org/x/mobile/cmd/gobind
I'm Stuck
Trying to modify the reverse project to do anything other than what it's already doing is failing. Even stuff like passing an object and calling toString will fail.
More to come...

Why checkStartAndEnd is not found in Android java.util.Arrays?

I look at Android source code
https://android.googlesource.com/platform/libcore/+/cff1616/luni/src/main/java/java/util/Arrays.java#1742
I realize Android's Arrays contains a public static method named checkStartAndEnd, which is not found in Java standard SE.
However, when I type java.util.Arrays.checkStartAndEnd in Android Studio, or look at the documentation https://developer.android.com/reference/java/util/Arrays.html, I realize checkStartAndEnd isn't valid for Android's Arrays class.
May I know why is it so? Am I looking at wrong Android source code?
You cannot see / use it because it's hidden (check the #hide tag in the Javadoc). If you compare the Android Arrays class with the Java SE one, you'll see that this checkStartAndEnd basically equals to rangeCheck, which is a private method there as well. As to why did they rename it? I have no idea, maybe some licensing issue or something else.

why Google calls variables with the prefix "m"?

why Google calls variables with the prefix "m" for example:
private int mSectionResourceId;
private int mTextResourceId;
I see it in all examples. But i not understand why they do it?
And now i have some example where it practic very good. If a called variabels without prefix i need write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
this.sectionResourceId = sectionResourceId;
this.textResourceId = textResourceId;
but if i use prefix i can write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
mSectionResourceId = sectionResourceId;
mTextResourceId = textResourceId;
I think it more readable. Who can explain to me the pros and cons of a prefix?
The variables starting with m are telling you they are variables in the scope of your class. Member of the class.
Link to Android Code Style Guide
The m just stands for 'Member'. It is simply declared that your Variable is a Class-Member.
It is more readable Code, because you know where Class Members got declared, so you can find it pretty fast. You don't need to write this, even if you don't prefix your Variables with an m.
In your Example, this only makes it more readable when there is no prefix-m. Another developer knows that it is a instance variable (member variable) and so declared on top or bottom of the class.
It is a prefix for class member variables. It's just a naming convention.
Mostly sure, taken from Hungarian Notation where similar prefix: m_ stands for exactly the same).
Referring to pros & cons:
Pros:
it allows to type fewer chars during programming,
programmers that are used to use Hungarian Notation may found it easier to follow the code.
Cons:
as the code changes very often, it is easy to forget about changing prefixes every time, when variable changes it's purpose (especially during prototyping),
it makes the code starts to smell bad,
Generally, it is some kind of reinventing the wheel. Java has this keyword that should be more than enough for accessing proper variable. If it's not, the code requires refactoring, maybe because of naming glitches or using too wide variable scopes.
Personally, I do not recommend to use Hungarian Notation (even the part of Android Code Style). We have great IDEs that increases the readability of the code.
There is an exception. The code, where Hungarian Notation (or more general, specific code style) was already been used. It is a matter of consistency.
The m is just a member variable. A class member if you will. Useable with constructors like WebView M WebView then later on you would use something like mWebView.loadurl("example.com"); it's just a placeholder for the variable you created. You don't have to add the member class variable as an m but it's more organized if you do

How to make a small change to Android source code, and incorporate into your own project

I want to make a small change to the Android standard TimePicker class. Specifically, I'm trying to change it so it works in 15 minute increments, rather than 1 minute increments.
This post helped me constrain the range of minute values to {0, 15, 30, 45}, as required in my app. But as I pointed out in a follow up comment, the minute spinner still shows previous minute as current value - 1, and the next minute as current value + 1, which creates a sloppy-feeling user interface.
I looked into the relevant Android source code, and it appears that the changes I would need to make are pretty simple. But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration, where to find Widget, how to resolve R.id variables, etc.
So my question is:
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
In my case, I just need to make a few small changes to TimePicker and NumberPicker, but I'm not sure how to properly set this up in my project.
Thanks for any suggestions.
But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration
Your source file's directory needs to match the package name. And since you cannot overwrite android.widget.TimePicker, you will either need to move that class to a new package or give it a new name.
where to find Widget
That implies that you copied TimePicker into one of your packages. That is fine, but then you need to add in the appropriate import statements for classes that TimePicker referred to from its original package. Or, you need to keep your (renamed) TimePicker in android.widget, adding this package to your project. This is rudimentary Java.
how to resolve R.id variables
If TimePicker relies upon resources that are not part of the Android SDK, you will need to copy those resources from the AOSP into your project as well.
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
IMHO, that cannot be answered readily in the abstract. Generally speaking, you do the sorts of things that I listed above.
You are best off subclassing the relevant classes and overriding the methods you would like to change.
In Java, you can do the following in a subclass:
The inherited fields can be used directly, just like any other
fields.
You can declare a field in the subclass with the same name as
the one in the superclass, thus hiding it (not recommended).
You can
declare new fields in the subclass that are not in the superclass.
The inherited methods can be used directly as they are.
You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
You can declare new methods in the subclass that are not in the superclass.
You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.
More info on subclassing in Java

Categories

Resources