如何使变量可从 Kotlin (Android) 中的 TimerTask() run 函数访问?

问题描述 投票:0回答:1

我正在开发一个项目,该项目由检索和写入

html_data
变量的函数以及每分钟调用它们的计时器组成。

我将之前的

html_data
保存到
prev_html_data
变量中,然后当它们不同时,我发送通知。

问题是该变量始终是一个空字符串(我初始化它的方式),这意味着它永远不会被覆盖。

html_data
工作得很好,并且以完全相同的方式初始化。

我什至将所有内容分离到一个函数中,这样我就可以从主类中调用它,但它仍然不起作用。

变量始终是一个空字符串,无论我做什么...每次打印它...

我还忘了提及,由于某种原因,我在timerRun()中打印的html_data从未被html_parse()解析,即使我在fetchdata()中调用该函数。

class MainActivity : AppCompatActivity() {
    var unique_id = 1000
    var html_data = ""
    var prev_html_data = ""
    lateinit var notificationManager: NotificationManager
    lateinit var notificationChannel: NotificationChannel
    lateinit var builder: Notification.Builder
    private val channelId = "hallomotto"
    private val description = "***** alert"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        fetchdata()
        this.prev_html_data = html_data
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.GREEN
            notificationChannel.enableVibration(true)
            notificationManager.createNotificationChannel(notificationChannel)

            builder = Notification.Builder(this, channelId)
                .setContentTitle("Floria alert!!")
                .setContentText("A new message has been posted (Floria is here!!!)")
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setLargeIcon(BitmapFactory.decodeResource(this.resources, R.drawable.ic_launcher_background))
        } else {

            builder = Notification.Builder(this)
                .setContentTitle("Floria alert!!")
                .setContentText("A new message has been posted (Floria is here!!!)")
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setLargeIcon(BitmapFactory.decodeResource(this.resources, R.drawable.ic_launcher_background))
        }

        val timer = Timer(true)
        timer.schedule(object : TimerTask() {
            override fun run() {
                timerRun()
            }
        }, 60000, 60000)
    }

    private fun fetchdata() {
        val volleyQueue = Volley.newRequestQueue(this)
        val url = "*****"

        val jsonRequest = JSONObject()
        jsonRequest.put("key", "*****")

        val jsonObjectRequest = JsonObjectRequest(
            Request.Method.POST,
            url,
            jsonRequest,
            { response ->
                val html_message = response.get("html_data")
                html_data = html_message.toString()
                display_html()
            },
            { error ->
                Toast.makeText(this, "Error has occurred when making the request", Toast.LENGTH_LONG).show()
                Log.e("MainActivity", "load_error: ${error.localizedMessage}")
            }
        )
        volleyQueue.add(jsonObjectRequest)
        Log.v("JSON request", jsonRequest.toString())
    }

    private fun html_parse() {
        html_data = """
            <html>
                <head>
                </head>
                <body>
        """.trimIndent() + html_data
        html_data += """
                </body>
            </html>
        """.trimIndent()
    }

    private fun display_html() {
        html_parse()
        Log.v("Output", html_data)
        val encoded_data = Base64.encodeToString(html_data.toByteArray(), Base64.NO_PADDING)
        val webview = findViewById<WebView>(R.id.webview)
        webview.loadData(encoded_data, "text/html", "base64")
    }

    private fun timerRun(){
        fetchdata()
        if(html_data != this.prev_html_data){
            notificationManager.notify(unique_id, builder.build())
            unique_id += 1
            Log.e("Match 1", html_data);
            Log.e("Match 2", this.prev_html_data)
        }
        this.prev_html_data = html_data
    }
}
android function kotlin variables
1个回答
0
投票

Volley 请求是异步的。

volleyQueue.add()
立即返回,请求将在一段时间后被处理。您可以在响应 lambda 中得到结果。

因此,当您调用

fetchdata()
时,在
fetchdata()
返回时尚未获取数据。但是,您当前的代码期望获取数据 is,因为它尝试读取
html_data
(
this.prev_html_data = html_data
)。那仍然是空字符串。

相反,您可以根据需要让

fetchdata()
填写
prev_html_data
,例如在第一次加载数据时,使用与设置
html_data
相同的响应 lambda。

© www.soinside.com 2019 - 2024. All rights reserved.