Как я могу обновить переменную внутри целого класса kotlin с помощью метода, а затем получить его обновленным с помощью другого вызова метода

1

Я написал класс kotlin с переопределенной забавой и забавой, чтобы обновить var в области видимости класса (я трагически новичок в Kotlin!)

class mySampleClass: sampleReference(){
    var varToBeUpdated:String = "my string" //var in class scope to be updated

    fun updateMyVar(gotString:String){

        //I tried this, it didn't work
        this.varToBeUpdated = gotString
        // also this didn't work
        varToBeUpdated = gotString

    }

    override fun sample(context: Context, intent: Intent){
        //here i need my varToBeUpdated with new string
        runSomeThing(varToBeUpdated)
        //some work to be done here
    }
}

В месте, где я вызываю методы, которые я делаю:

myObject.updateMyVar("new string")
myObject.sample()

Интересно, как я могу обновить переменную, в которой я нуждаюсь, так как я не могу добавить новые аргументы в "забавном образце", потому что он переопределяет метод класса

Заранее спасибо, наилучшие пожелания всем :)



ОБНОВЛЕНИЕ: добавьте мой фактический код из-за того, что класс, кажется, не может сохранять правильное обновленное значение, когда я вызываю переопределенный метод:

Вот мой BroadcastReceiver, чтобы проверить, завершена ли загрузка, и выполнить некоторые действия

class DownloadBroadcastManager: BroadcastReceiver() {

    var myClassFilename:String = "default"
    var myClassExtension:String = ".default"

    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action

        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE == action) {
            //Show a notification
            // here there a log to check if var are updated
            println("myTag - variables $myClassFilename, $myClassExtension")

            Toast.makeText(context, "Download of $myClassFilename$myClassExtension completed", Toast.LENGTH_LONG).show()
            // richiama azioni come player o display image o altro?

            //player
            var uri = Uri.parse (Environment.getExternalStorageDirectory().getPath() + "/Download/$myClassFilename$myClassExtension") //myClassExtension is ".mp3", dot is included, however it seems class is re-intialized as i call the method
            println("myTag - uri: $uri")
            println("myTag - context: $context")

            var mPlayer = MediaPlayer() // I added this declaration (that be re-done later) cause I had a problem in making the player running (of course giving it a valid path to a valid file). Now this is "junk code"
            mPlayer.stop()
            mPlayer.reset()
            mPlayer.release()
            mPlayer = MediaPlayer.create(context, uri) // here there the proper declaration + initialization
            mPlayer.start()

        }
    }
}

Вот часть из моего DownloaderClass...

var brReceiver = DownloadBroadcastManager()
    // shows when download is completed
    println("myTag - ${brReceiver.myClassFilename}, ${brReceiver.myClassExtension}: originals") //here shows the default: it right
    val intent = Intent(context, MainActivity::class.java)
    brReceiver.myClassFilename = myTitle // inject filename
    brReceiver.myClassExtension = ".mp3" // inject file extension
    println("myTag - ${brReceiver.myClassFilename}, ${brReceiver.myClassExtension}: modified") // here it shows my class property as correctly updated

    brReceiver.onReceive(context, intent) // here, as calling the override fun, it get back to default value of the property
Теги:
kotlin
broadcastreceiver
android-broadcastreceiver

3 ответа

1
Лучший ответ

Вы можете просто сделать следующее:

  1. Избавьтесь от функции updateMyVar:

    class MySampleClass: SampleReference(){
        var varToBeUpdated:String = "my string" //var in class scope to be updated
    
        override fun sample(context: Context, intent: Intent){
            //here i need my varToBeUpdated with new string
            runSomeThing(varToBeUpdated)
            //some work to be done here
        }
    }
    
  2. Обновите свойство varToBeUpdated напрямую:

    val myObject = MySampleClass()
    myObject.varToBeUpdated = "new string"
    myObject.sample()
    

Обновление: если вы вызываете brReceiver.onReceive(...) значения в DownloadBroadcastManager обновляются. Но ты не должен этого делать. Платформа Android называет это для вас. И когда это происходит, создается новый экземпляр класса DownloadBroadcastManager и устанавливаются значения по умолчанию. Мы используем Intents для передачи данных в BroadcastReceiver, например, вызываем intent.putExtra("filename", "yourFileName") при создании BroadcastReceiver и вызываем intent.getStringExtra("filename") в функции onReceive() для получения значения. Вот как передать/получить данные в/из BroadcastReceiver

  • 0
    Я думаю, что это решение нарушает принцип инкапсуляции.
  • 0
    Нет, это не так. У Kotlin есть понятие свойств kotlinlang.org/docs/reference/properties.html . Чтобы использовать свойство, мы просто ссылаемся на него по имени. varToBeUpdated является свойством. Получатель и установщик не являются обязательными.
Показать ещё 6 комментариев
1

Accoirding в Котлин документы вы можете определить getter и setter методы для любой переменной, как таким образом:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

в вашем случае это может быть что-то вроде:

var varToBeUpdated:String = "my string"
    get() = field
    set(value) { field = value }
0

Хорошо, сначала спасибо М.СамиАзар, и особенно Сергею, за их ответы и за невероятное терпение! К сожалению, кажется, что, поскольку он повторно инициализируется платформой, BroadcastReceiver также теряет все дополнительные функции, которые я ранее поместил в переменную Intent. Я наконец решил эту проблему, позволив мне получить нужные мне строки, записав только строку текста в файл во внутреннем хранилище и получив ее в своем классе BroadcastReceiver. Вот код:

это мой метод onReceive в классе BroadcastReceiver

 override fun onReceive(context: Context, intent: Intent) {
    val action = intent.action
    Log.i("Receiver", "myTag - Broadcast received: " + action)
    var myFilename = "deafult"

    if (DownloadManager.ACTION_DOWNLOAD_COMPLETE == action) {

        // read the previously created file from internal storage
        var fileInputStream: FileInputStream? = null
        fileInputStream = context.openFileInput("storeDownloadedData")
        var inputStreamReader: InputStreamReader = InputStreamReader(fileInputStream)
        val bufferedReader: BufferedReader = BufferedReader(inputStreamReader)

        // here setting string var and stringbuilder var to catch the text updated outside the while loop
        val stringBuilder: StringBuilder = StringBuilder()
        var text: String? = null
        var sumText:java.lang.StringBuilder? = null
        // while loop for reading the file line by line (in this case the file can contains just one line a time)
        while ({ text = bufferedReader.readLine(); text }() != null) {
            sumText = stringBuilder.append(text)
        }

        // convert stringBuilder to a list of string splitting the original string obtained by file reading
        var secondText:String = "default"
        println("myTag - text: $text, $sumText")
        if (sumText != null){
            secondText = sumText.toString()
            var listFromText = secondText.split(",")
            // set filename to the title contained in the string
            myFilename = listFromText[0]
        }

        //player - finally play the file retrieving the title from the file in internal storage
        var uri = Uri.parse (Environment.getExternalStorageDirectory().getPath() + "/Download/$myFilename.mp3")
        println("myTag - uri: $uri")
        println("myTag - context: $context")

        var mPlayer = MediaPlayer.create(context, uri)
        mPlayer.start()

    }

это код, добавленный в мой класс DownloadManager:

// strore into an internal storage file the data of title and extensione for the file gonna be downloaded
    val myStoredFile:String = "storeDownloadedData"
    val data:String = "$myTitle,.mp3"
    val fileOutputStream: FileOutputStream
    // write file in internal storage
    try {
        fileOutputStream = context.openFileOutput(myStoredFile, Context.MODE_PRIVATE)
        fileOutputStream.write(data.toByteArray())
    }catch (e: Exception){
        e.printStackTrace()
    }

    // it notifies when download is completed
    val intent = Intent(context, MainActivity::class.java)
    var brReceiver = DownloadBroadcastManager()

Я не знаю, если это "ортодокс", но, похоже, работает АТМ :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню