【问题标题】:Why can't I access a global variable from AsyncTask? [duplicate]为什么我不能从 AsyncTask 访问全局变量? [复制]
【发布时间】:2019-05-04 00:00:33
【问题描述】:

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

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

【问题讨论】:

    标签: android kotlin android-asynctask


    【解决方案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 {}
    }
    

    这是在 Kotlin 中吗:

    class MyClass {
        inner class Something 
    }
    

    【讨论】:

      【解决方案2】:

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

      这里是推荐人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()
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-07-03
        • 2014-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-02
        • 1970-01-01
        • 2019-11-09
        相关资源
        最近更新 更多