首页 > 解决方案 > 为什么我不能从 AsyncTask 访问全局变量?

问题描述

我正在尝试一些事情并偶然发现了一个问题,即我无法str1从 class访问全局变量MyAsyncTask。我猜,它一定是一些声明错误,但我不太确定违反了什么。

class MainActivity : AppCompatActivity() {
    var str1 = "0"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        for (i in 0..5){
            val myAsyncTask = MyAsyncTask(this@MainActivity)
            myAsyncTask.execute("-")
            str1 = str1 + "1"
        }

    }
    class MyAsyncTask(private var c : Context):AsyncTask<String,Void,String>(){

        override fun doInBackground(vararg str: String?): String {
            str1 = str1 + str[0] + "2" // str1 is bolded in red, somehow, i cant access it
            return str1
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            Toast.makeText(c, result, Toast.LENGTH_SHORT).show()
        }
    }
}

标签: androidkotlinandroid-asynctask

解决方案


作为一般规则,如果您在 Kotlin 中有一些类似语法的东西可以在 Java 中工作,请反编译 Kotlin 代码。在 IntelliJ/Android Studio 中,工具 -> Kotlin -> 显示 Kotlin 字节码。稍微编辑一下代码就可以编译,你会看到类的声明是public static final class MyAsyncTask extends AsyncTask. 如果您熟悉内部类的工作原理,您就会知道静态内部类就像在单独的文件中声明它们一样;它们没有与其外部类相关的上下文,因此无法访问非静态变量。这有点像从伴随对象或静态方法访问非静态变量。静态任何东西都不会附加到对象的特定实例,因此不能访问非静态变量。

那就是问题所在。如果你从这里搜索你想要的东西,你通常可以找到文档的链接,至少对于基本的语言相关的东西。

如果你想要常规的内部类,Kotlin 有一个特殊的关键字必须使用。关键字也很简单:它是inner. 将您的类声明更改为inner class MyAsyncTask,反编译,并查看它如何更改为public final class MyAsyncTask extends AsyncTask.

TL;博士:

这在Java中:

public class MyClass {
    public class Something {}
}

这是在 Kotlin 中:

class MyClass {
    inner class Something 
}

推荐阅读