Android 如何通过一个方法更新整个kotlin类中的变量,然后通过另一个方法调用检索更新的变量

Android 如何通过一个方法更新整个kotlin类中的变量,然后通过另一个方法调用检索更新的变量,android,kotlin,broadcastreceiver,android-broadcastreceiver,Android,Kotlin,Broadcastreceiver,Android Broadcastreceiver,我编写了一个kotlin类,其中包含一个被覆盖的乐趣,以及将var更新到类作用域中的乐趣(不幸的是,我对kotlin还不熟悉!) 在我调用方法的地方,我会: myObject.updateMyVar("new string") myObject.sample() 我想知道如何更新我需要的var,因为我无法在“fun sample”中添加新的参数,因为它覆盖了一个类方法 提前感谢,向大家致以最良好的问候:) 更新:添加我的实际代码,因为在我调用overrid方法时,类似乎无法保持正确的更新值

我编写了一个kotlin类,其中包含一个被覆盖的乐趣,以及将var更新到类作用域中的乐趣(不幸的是,我对kotlin还不熟悉!)

在我调用方法的地方,我会:

myObject.updateMyVar("new string")
myObject.sample()
我想知道如何更新我需要的var,因为我无法在“fun sample”中添加新的参数,因为它覆盖了一个类方法

提前感谢,向大家致以最良好的问候:)



更新:添加我的实际代码,因为在我调用overrid方法时,类似乎无法保持正确的更新值:

这是我的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's 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's 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's the proper declaration + initialization
            mPlayer.start()

        }
    }
}
这是我的下载课上的部分

var brReceiver = DownloadBroadcastManager()
    // shows when download is completed
    println("myTag - ${brReceiver.myClassFilename}, ${brReceiver.myClassExtension}: originals") //here shows the default: it's 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的文档,您可以为任何变量定义
getter
setter
方法,如下所示:

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

您只需执行以下操作:

  • 摆脱
    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
        }
    }
    
  • 直接更新
    varToBeUpdated
    属性:

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

  • 更新:
    如果调用
    brReceiver.onReceive(…)
    将更新
    下载广播管理器中的值。但你不应该那样做。Android框架为您调用它。当它发生时,将创建
    DownloadBroadcastManager
    类的新实例,并设置默认值。我们使用intent将数据传递给
    BroadcastReceiver
    ,例如在创建
    BroadcastReceiver
    时调用
    intent.putExtra(“文件名”、“您的文件名”)
    ,并在
    onReceive()
    函数中调用
    intent.getStringExtra(“文件名”)
    以获取值

    好的,首先感谢萨米亚扎尔先生,特别是谢尔盖,感谢他们的回答和难以置信的耐心! 不幸的是,当框架重新初始化时,BroadcastReceiver似乎也会丢失我之前在Intent变量中添加的任何额外内容。 我最终解决了这个问题,让我检索所需的字符串,只需将一行文本写入内部存储器中的文件,然后在BroadcastReceiver类中检索它。 代码如下:

    这是我在BroadcastReceiver类中的“onReceive”方法

     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's 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()
    
    我不知道这是否是“ortodox”,但它似乎能工作
    :)

    如果您将
    varToBeUpdated
    公开,您可以使用
    myObject.varToBeUpdated=“my string”
    访问它,也许我现在的问题是我没有公开它?嗯:没什么可做的。当我调用该方法时,有什么东西再次声明了我的var,或者有什么东西阻止了我更新它们
    var mPlayer=MediaPlayer()//我添加了这个声明(稍后会重新执行),因为我在使播放器运行时遇到了问题(当然是给它一个有效文件的有效路径)。现在这是“垃圾代码”
    您可能应该删除它。如果您调用
    brReceiver.onReceive(…)
    下载广播管理器中的值将更新。但你不应该那样做。Android框架为您调用它。当它发生时,将创建
    DownloadBroadcastManager
    类的新实例,并设置默认值。我们使用意图将数据传递给BroadcastReceiver,例如,在创建BroadcastReceiver时调用
    intent.putExtra(“文件名”、“您的文件名”)
    ,并在
    onReceive()函数中调用
    intent.getStringExtra(“文件名”)
    。真的非常感谢!我认为这个解决方案违反了封装原则。不,它没有。科特林有财产的概念。要使用属性,我们只需按名称引用它
    varToBeUpdated
    是一个属性。getter和setter是可选的。我现在只能在pc上工作。。似乎有什么东西阻止了这一切。该对象是否可以重新初始化,但我没有注意到?您可以在Android Studio中进行检查,通过右键单击底部窗口的属性->查找用法->查找
    值写入
    下拉列表来更新该值。当您单击它时,您将获得更新属性的所有位置。好的,我尝试使用println()查找用法,并将一些输出发送到控制台。我的结果是,在MainActivity中,更新得到确认:println(myObject.varToBeUpdated)//resutl这里是默认的myObject.varToBeUpdated=“new string”//新的值注入println(myObject.varToBeUpdated)//控制台中的结果这里是新的!myObject.sample()//在这里它使用默认值再次工作。。。这是怎么回事?提前感谢,向brReceiver.onReceive致意(上下文、意图)
     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()
    
        }
    
    // strore into an internal storage file the data of title and extensione for the file's 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()