简体   繁体   中英

Unresolved reference: method of extended class in Kotlin

I have a variable in my class that extends BroadcastReceiver and implements one additional method called isNetworkAvailable . When I call the method within the class it works but it results in "Unresolved reference" when called from outside. The preexisting methods of the class are also accessible.

Any ideas?

class MainActivity : AppCompatActivity() {

    private var connectivityReceiver: BroadcastReceiver = object: BroadcastReceiver(){

        override fun onReceive(context: Context, arg1: Intent) {
            if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
                // ...
            }
        }

        fun isNetworkAvailable(context: Context?): Boolean {
            // ...
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        connectivityReceiver.onReceive() // Accessible if arguments are provided 
        connectivityReceiver.isNetworkAvailable(this@MainActivity) // ERROR: Unresolved reference
    }
}

You're variable connectivityReceiver is of type BroadcastReceiver , which has no method isNetworkAvailable . Unfortunately, it's not as simple as this because for Kotlin connectivityReceiver is nothing but a BroadcastReceiver .

To make your method available you can create a specific class and not an anonymous object.

class MyBroadcaseReceiver : BroadcastReceiver(){

    override fun onReceive(context: Context, arg1: Intent) {
        if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
            // ...
        }
    }

    fun isNetworkAvailable(context: Context?): Boolean {
        // ...
    }
}

Then in the activity just use

private var connectivityReceiver: MyBroadcaseReceiver = MyBroadcaseReceiver()

Note that if you do something like

private var connectivityReceiver: BroadcaseReceiver = MyBroadcaseReceiver()

you'll end up in the same issue since connectivityReceiver will be a BroadcastReceiver and not the class where isNetworkAvailable is defined.


There's also the possibility of just removing the explicit type:

private var connectivityReceiver = object: BroadcastReceiver(){

    override fun onReceive(context: Context, arg1: Intent) {
        if ( isNetworkAvailable(this@MainActivity) ) { // Works just as it's supposed to.
            // ...
        }
    }

    fun isNetworkAvailable(context: Context?): Boolean {
        // ...
    }
}

Kotlin's inference should be able to pick up the method then. The reason why I think this is not a great approach is because it only works if you want to keep this object expression private - see object expressions

Note that anonymous objects can be used as types only in local and private declarations. If you use an anonymous object as a return type of a public function or the type of a public property, the actual type of that function or property will be the declared supertype of the anonymous object, or Any if you didn't declare any supertype. Members added in the anonymous object will not be accessible.

Basically means in your case if you remove private the member isNetworkAvailable won't be accessible anymore. I believe code is meant to change a lot and especially a class like that eventually should go to its own place as it becomes more complex and makes it easier to test. This is of course just a personal opinion.

@Fred answer is correct, it is because compiler don't know that the BroadcastReceiver has the function called isNetworkAvailable .

Kotlin is strong in type interference, you don't need to specify explicitly that the variable is of type BroadcastReceiver it tells the compiler that the object is of type BroadcastReceiver which does not have any function called isNetworkAvailable() .

Just remove the explicit type declaration from the variable

private var connectivityReceiver = object: BroadcastReceiver() {...}

Kotlin will automatically assign the correct type using its inferred type of anonymous object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM