【问题标题】:updating UI thread while in asynctask在异步任务中更新 UI 线程
【发布时间】:2014-03-07 18:29:34
【问题描述】:

正如标题所述,我试图在运行 asynctask 时更新我的​​ UI 线程中的某些内容。我已经阅读了很多关于 asynctask 的内容,看来我应该能够更改 onPostExecute() 方法中的变量。显然情况并非如此。

这是我的示例代码:

TextView tv = (TextView) findViewById(R.id.thingsThatNeedToBeUpdated); 
Login login = new Login();
login.execute(userName, password);

这里是登录类

public class Login extends AsyncTask<String, void, String>{
    public String doInBackground(String... params){
       logMeIn(params[0], params[1]);
    }
    public void onPostExecute(String update){
       tv.setText(result); //this is not working!!
    }

实际发生的事情是电视带有红色下划线,eclipse 说我需要创建一个局部变量.. 但我认为 onPostExecute 是从 UI 线程运行的?困惑:?
我正在尝试做我在this 网站上找到的东西。我不完全确定我在做什么,我会喜欢正确的方向!提前致谢。

【问题讨论】:

  • 我更新了问题以进一步确定问题
  • 登录在不同的 .java 类中?
  • 你在哪里实例化电视?因为 findViewById() 肯定会在您的 activesync 中返回 null 吗?
  • 老实说,要为您指明正确的方向,您应该阅读一本好的 Java 书籍,似乎您对变量范围一无所知,这是在 Android 中前进之前的基本知识......
  • 谢谢,我解决了这个问题并接受了我用来解决这个问题的答案!

标签: java android multithreading android-asynctask


【解决方案1】:

这一行在这里

TextView tv = (TextView) findViewById(R.id.thingsThatNeedToBeUpdated);

显然也声明了

  1. 在方法之外 - 这将导致 tv 成为 null
  2. 在不属于AsyncTask 的方法中,这意味着 任务无权访问它

您应该将其定义为成员变量(在方法之外)

TextView tv;

然后在方法中初始化它

tv = (TextView) findViewById(R.id.thingsThatNeedToBeUpdated);

这将使您的任务以及您班级的其他成员都可以访问它。

如果您的 AsyncTask 与您的 Activity 是一个单独的文件,那么您将希望 see this answer 使用 interface 并创建回调以更新您的 Activity 中的 TextView

【讨论】:

  • 这很有帮助。我的 AsyncTask 在它自己的 .java 文件中,所以我的问题是范围问题。我通过将我的 textView 传递给我的 AsyncTask 类的构造函数来解决这个问题。谢谢!!
【解决方案2】:

TextView tv; 放在类的范围内和函数之外。将tv = (TextView) findViewById(R.id.thingsThatNeedToBeUpdated); 留在原处。然后您应该能够从onPostExecute() 访问tv

【讨论】:

    【解决方案3】:

    这是因为 TextView 变量 tv 是在另一个没有 Login 作为内部类的类中定义的。如果 Login 是包含变量 tv 的类的内部类,它应该可以看到变量 tv。

    解决这个问题的一个简单方法是让 AsyncTask 成为主类的内部类。

    【讨论】:

      【解决方案4】:

      要将您的 TextView 实例带入范围,请将您的 tv 变量传递给您的 Login 实例构造函数,并添加构造函数和变量,如下所示。

      public class Login extends AsyncTask<String, void, String>{
      
          private TextView tv;
      
          public Login(TextView tv){
             this.tv = tv;
          }
          public String doInBackground(String... params){
             logMeIn(params[0], params[1]);
          }
          public void onPostExecute(String update){
             tv.setText(result); //this should work
          }
      }
      

      您必须将变量传递给此实例,否则它超出范围。除非您在 Login 类中声明和实例化一个新变量,否则您将无法访问它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-07
        • 2014-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多