【问题标题】:How to assign global variables with AsyncTask如何使用 AsyncTask 分配全局变量
【发布时间】:2013-12-15 12:31:04
【问题描述】:

这里我举了一个小例子来说明我在使用全局变量和 AsyncTasks 时遇到的问题。我已经从文件中读取数据并将该数据分配给字符串,并在 onPostExecute() 方法中将该字符串分配给全局变量。但是,当我为 TextView 分配“aString”变量时,输出仍然是“无”。

我知道,如果您在 onPostExecute() 方法中进行 TextView 分配,它会起作用,但是如果我想在 AsyncTask 之外的方法中使用数据怎么办。

有人可以帮忙吗,我想我没有得到什么?

public class GoodAsync extends Activity{

    TextView tv;
    String aString = "nothing";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.asynctasks);

        new AsyncTasker().execute();

        tv = (TextView) findViewById(R.id.async_view);
        tv.setText(aString);

    }

    private class AsyncTasker extends AsyncTask<String, Integer, String>{

        @Override
        protected String doInBackground(String... arg0) {

            AssetManager am = GoodAsync.this.getAssets();
            String string = "";
            try {
                // Code that reads a file and stores it in the string variable

                return string;

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            aString = result;
        }   

    }
}

【问题讨论】:

    标签: java android android-asynctask global-variables


    【解决方案1】:

    也许你想这样做:

    public class GoodAsync extends Activity{
    
    TextView tv;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.asynctasks);
        tv = (TextView) findViewById(R.id.async_view);
        new AsyncTasker().execute();
    }
    
        public void setTextView (String text) {
           tv.setText(text);
        }
    
        private class AsyncTasker extends AsyncTask<String, Integer, String>{
    
            ....
    
            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                setTextView(result);
            }   
    
        }
    }
    

    【讨论】:

    • 这是一个比使用 get() 更好的解决方案,如果您的任务花费的时间超过一秒,它会导致您的 UI 冻结。
    【解决方案2】:

    您确定您的 AsyncTask 正在按时执行吗?

    例如,您正在这样做:

    new AsyncTasker().execute();
    tv = (TextView) findViewById(R.id.async_view);
    tv.setText(aString);
    

    这会设置任务进行,但随后会立即将 TextView 的值设置为 aString 变量。

    此时 AsyncTask 很可能仍在执行,因此 aString 仅在代码执行后获得“nothing”以外的值。

    【讨论】:

      【解决方案3】:

      你不是在等待你的 asynctask 完成..你可以这样做..

      new AsyncTasker().execute().get();
      tv = (TextView) findViewById(R.id.async_view);
      tv.setText(aString);
      

      【讨论】:

      • 哦,对了,我明白了。所以上面的代码会等到 AsyncTask 完成,用 .get() 方法获取 ArrayList 然后设置,对吗?
      • 不完全...get() 基本上用于等待线程完成..但是,在主 UI 线程中使用 .get() 不是一个好习惯,因为它导致你的用户界面冻结..所以更好的是你应该在 onPostExecute() 中将值设置为你的 textview ...
      • @Vikram 请不要发布这样的建议,然后使用评论指出遵循我的建议不是一个好习惯。在 AsynTask 上使用 get() 与此 AsyncTask 相矛盾!
      • @Baschi:我知道,但是提问者已经定义了他知道使用 onPostBackground() 方法的情况......我写了这个,因为可能是他有一些特定的场景或正在寻找一个这样做的替代方法……是的,让他意识到事情也是必要的……:)
      猜你喜欢
      • 2014-07-20
      • 2017-08-19
      • 2017-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多