为什么我不能从AsyncTask访问全局变量?

时间:2018-12-02 14:17:43

标签: android kotlin android-asynctask

我正在尝试某些事情,偶然发现一个问题,我无法从类str1访问全局变量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()
        }
    }
}

2 个答案:

答案 0 :(得分:1)

通常,如果您在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; DR:

这在Java中:

public class MyClass {
    public class Something {}
}

这是科特林的吗?

class MyClass {
    inner class Something 
}

答案 1 :(得分:0)

要访问外部类的成员,您必须与Java不同,必须在kotlin中使用内部类。

这是裁判https://kotlinlang.org/docs/reference/nested-classes.html#inner-classes

所以您的代码应该像...

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

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

    inner 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()
        }
    }
}