How to define a public static Boolean in Kotlin - android

I wanted to know how I define a static variable in Kotlin that can be used in other classes that do not final. Because the data is changing.
Example Java:
public static Boolean ActivityIsRuning = false;

There are three ways to achieve this:
1) Top-level / global declaration
Declare a variable outside of any class or function and it will be accessible from anywhere:
var activityIsRunning = false
2) object (an out of the box singleton)
object StaticData {
var activityIsRunning = false
}
Accessable like this:
StaticData.activityIsRunning
3) Class with companion object (as Todd already suggested)
class Config {
companion object {
var activityIsRunning = false
}
}
Accessable like this:
Config.activityIsRunning

You have to create companion object for this.
Your code in Kotlin would look something like this:
class Foo {
companion object {
lateinit var instance: Foo
}
init {
instance = this
}
}

You can define static variables in the companion object of any class. If you make it a var instead of a val, it can change values:
class MyClass {
companion object {
var activityIsRunning: Boolean = false
}
}

Adding to #Todd and #Willi Mentzel, if you like to group those settings under a common area, you can use a top-level plain object.
object GlobalSettings{
var isHomeActivityRunning = false
var isDrinkingCocoCola = true
}
and this can be accessed anywhere in the code (inside an Activity, Service, or anywhere) like this:
if( GlobalSettings.isDrinkingCocoCola ){
// do something
} else {
GlobalSettings.isDrinkingCocoCola = false
}

Related

How to refer to a field of a Class in other Class?

There is integer variable 'a' in Class A, and method
Class A {
var a = 0
fun setA(int: Int) {
a = int
}
}
I used it in Class B by
Class B {
var classA = A()
classA.setA(10)
}
Then I want to set a to 100 in another class, Class C
But If I declare classA as A() and classA.setA(100) in same method of B, this doesn't change value of a referred in class B.
How to globally change the value of a in one place so that it's the same for all other classes?
class A {
companion object {
var a: Int = 0
}
}
perhaps you're looking for a companion object ? this allows global access to the same instance of a
you can now do:
A.a = 5
or in your case :
fun changeValue(int: Int) {
a = int
}
and this value will be the same everywhere
if you're trying to read the value back:
var example = A.a
note how I'm not creating an instance of A anywhere, because using a companion object is the same as using static in java, basically meaning that you can treat this as if an instance already exists

How to use a property from a constructor inside an instance method in Kotin?

This is my code.
class Repository(context: Context) {
// Can access 'context' from here
val mSharedPrefsProperties = context
.getSharedPreferences(context.packageName.plus(".properties"), Context.MODE_PRIVATE)
// Can't access 'context' in this function (unresolved reference: context)
private fun getApiKey(): String {
val apiKeys = context.resources.getStringArray(R.array.api_keys)
val random = Random().nextInt(apiKeys.size)
return apiKeys[random]
}
}
Is there a way to access the properties from the constructor inside functions or do I need to make them a instance/local variable?
Just put var (or val) on the arguments
class Repository(var context: Context) {
// Can access 'context' from here
val mSharedPrefsProperties = context
.getSharedPreferences(context.packageName.plus(".properties"), Context.MODE_PRIVATE)
// Can't access 'context' in this function (unresolved reference: context)
private fun getApiKey(): String {
val apiKeys = context.resources.getStringArray(R.array.api_keys)
val random = Random().nextInt(apiKeys.size)
return apiKeys[random]
}
}
Simple constructor parameters don't become properties of your class. That only happens by explitly making them var or val. You can, nevertheless, access those simple params in anything related to initialization, for example:
class ConstWithArg(param1: String) {
init {
println(param1)
}
val field1 = param1.length
var field2 = param1.length
}
If you need to access the parameter after construction, it should become a property by making it a val. If you don't want anyone else to access this field outside your class, mark it as private:
class ConstWithArg(private val param1: String) {
fun useProp(){
println(param1)
}
}

How to observe a boolen field with RxJava

In my class Foo I have a boolen field. When the field changes I will react on this change in my class Bar
How can I implement this with RxJava in Android?
I guess you have to create class Foo with subject inside
class Foo {
var booleanField: Boolean = false
set(value) {
field = value
observable.onNext(value)
}
val observable = BehaviorSubject.createDefault(booleanField)
}
Then you have to observe that subject inside Boo class
class Boo(val observable: BehaviorSubject<Boolean>) {
var booleanField: Boolean = false
var disposable: Disposable? = null
fun startObserve() {
disposable?.dispose()
disposable = observable.subscribe {
booleanField = it
}
}
fun finishObserve() {
disposable?.dispose()
disposable = null
}
}
If you have to run it just create Foo and pass it's subject to Boo:
val foo = Foo()
val boo = Boo(foo.observable)
boo.startObserve()
foo.booleanField = true //boo is changed to true too
now if you change foo.booleanField, boo.booleanField will change too.
If you need, you can run startObserve in constructor to start it immidiatly after creating instance.
May be you have to create BehaviorSubject somewhere else and just pass to both classes using DI.
And do not forget to unsubscribe after work is done.

Kotlin property with getter. Can I not specify an initial value?

I want to create a singleton class, but unfortunately, Android needs Context for almost anything so I need it to create an instance. So I just assumed the user called init(), and then return the instance. As you see below, if the _instance is null, an exception will be thrown, so the get method cannot return null.
But Kotlin says I must initialise instance. The things is, that MyClass cannot be created without a context. So I would like not to specify an initial value. How can I do that?
companion object
{
protected var _instance:MyClass? = null;
fun init(context:Context)
{
_instance = MyClass(context)
}
var instance:MyClass //<---This causes a compile error.
get()
{
if(_instance==null) throw RuntimeException("Call init() first.");
return _instance!!;
}
}
Change the var to val and it should work:
....
val instance: MyClass
....
A variable property (var) not only assumes a getter, but also a setter. Since you provided no setter, a default one was generated set(value) { field = value }. Despite is uselessness in this situation, the default setter uses field, thus requires its initialization.
Use lateinit property
public class MyTest {
lateinit var subject: TestSubject
fun setup() {
subject = TestSubject()
}
fun test() {
subject.method()
}
}

Kotlin: How to access field from another class?

package example
class Apple {
val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}
Class:
package example
class Store {
fun buy() {
val SIZE = Apple.APPLE_SIZE_KEY
}
}
Error:
'APPLE_SIZE_KEY' has private access in 'example.Apple'
But official documentation describes that if we do not specify any visibility modifier, public is used by default.
Why is above error coming?
What you are trying to do is accessing a value of a class that has no instance. Here are three solutions:
package example
object Apple {
val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}
This way you do not need to instantiate anything because of the way objects work in Kotlin.
You could also just instantiate your class like this:
package example
class Store {
fun buy() {
val SIZE = Apple().APPLE_SIZE_KEY
}
}
In this solution you also have an object of Apple, but Apple is still declared as a class.
The third option is a companion object, which behaves like static variables in Java.
package example
class Apple {
companion object {
val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}
}
If you want this to be a class level property instead of an instance level property, you can use a companion object:
class Apple {
companion object {
val APPLE_SIZE_KEY: String = "APPLE_SIZE_KEY"
}
}
fun useAppleKey() {
println(Apple.APPLE_SIZE_KEY)
}
What you currently have is an instance property, which you could use like this:
fun useInstanceProperty() {
val apple = Apple()
println(apple.APPLE_SIZE_KEY)
}

Categories

Resources