Activity 的实例变量未在 AsyncTask 的 onPostExecute 中设置或如何将数据从 AsyncTask 返回到主 UI 线程 [英] Instance variable of Activity not being set in onPostExecute of AsyncTask or how to return data from AsyncTask to main UI thread

查看:21
本文介绍了Activity 的实例变量未在 AsyncTask 的 onPostExecute 中设置或如何将数据从 AsyncTask 返回到主 UI 线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出创建 AsyncTask 的正确方法,以从 Internet 检索一些数据,然后获取该数据并将其捆绑在一个 Intent 中并将其传递给一个新活动(列表显示).所以在第一个活动中,我只有一个 EditText 和一个按钮.在 OnClick 事件中,应该调用任务,当它完成时,数据应该捆绑在一个 Intent 中并传递给下一个 Activity.问题是当我从 onPostExecute 获取结果并将它们设置为主要活动的实例变量时,当任务完成时,该实例变量仍然为空.这是代码的准系统版本:

I'm trying to figure out the correct way to create an AsyncTask to retrieve some data from the internet and then to take that data and bundle it up in an Intent and pass it to a new activity(A list display). So in the first activity I just have an EditText and Button. In the event of an OnClick the task should be called and when it is finished the data should be bundled inside an Intent and passed to the next Activity. The problem is when I take the results from onPostExecute and set them to an instance variable of the main activity, that instance variable is still null when the task is complete. Here is the barebones version of the code:

public class SearchActivity extends Activity implements OnClickListener
{
    static final String TAG = "SearchActivity";
    private EditText searchInput;
    private Button searchBtn;
    private PlacesList places;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search_activity);

        searchBtn = (Button) findViewById(R.id.button_search);  
        searchInput = (EditText) findViewById(R.id.search_input);

        searchBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
        if(v == searchBtn)
        {
            String input = searchInput.getText().toString();
            if(input != null && input.length() != 0)
            {

                try {
                    new TestTask().execute(input);
                    Bundle bundle = new Bundle();
                    bundle.putParcelable("places", places);
                    Intent i = new Intent(this, SearchResultsActivity.class);
                    i.putExtras(bundle);

                    startActivity(i);
                } catch(Exception ex) {
                    ex.printStackTrace();
                } 
            }
        }
    }

    private class TestTask extends AsyncTask<String, Void, PlacesList>
    {
        private ProgressDialog dlg = new ProgressDialog(SearchActivity.this);

        @Override
        protected void onPreExecute()
        {
            dlg.setMessage("test");
            dlg.show();
        }

        @Override
        protected PlacesList doInBackground(String...args)
        {
            try 
            {
                return new PlaceLocator().retrieveResults(args[0]);
            } 
            catch (Exception e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return new PlacesList();
        }

        @Override
        protected void onPostExecute(PlacesList results)
        {
            SearchActivity.this.places = results;
            if(dlg.isShowing())
                dlg.dismiss();
        }
    }
}

当我调试应用程序时,我看到 onPostExecute 确实包含一个充满结果的有效 PlacesList,那么为什么在执行任务后实例变量 Places 设置为 null?我要从 AsyncTask 错误地返回数据"?

When I debug the application I see onPostExecute does contain a valid PlacesList full of results, so why is the instance variable places set to null after the task is executed? I am going about "returning data" from an AsyncTask incorrectly?

推荐答案

根据定义,AsyncTask 在不同的线程中执行.因此,您不能期望在您调用 execute 后立即获得结果.相反,您应该在 AsyncTask 完成后触发新的意图:

An AsyncTask is, by definition, executed in a different thread. Thus, you cannot expect the results to be immediatly available after you call execute. Instead, you should trigger the new intent off of the completion of the AsyncTask:

public void onClick(View v) {
        if(v == searchBtn)
        {
            String input = searchInput.getText().toString();
            if(input != null && input.length() != 0)
            {

                try {
                    new TestTask().execute(input);

                } catch(Exception ex) {
                    ex.printStackTrace();
                } 
            }
        }
    }

private void startSearch(PlaceList places) {
  Bundle bundle = new Bundle();
  bundle.putParcelable("places", places);
  Intent i = new Intent(this, SearchResultsActivity.class);
  i.putExtras(bundle);

  startActivity(i);
}

private class TestTask extends AsyncTask<String, Void, PlacesList>
{
...

        @Override
        protected void onPostExecute(PlacesList results)
        {
           startSearch(results);
           if(dlg.isShowing())
                dlg.dismiss();
        }

}

这篇关于Activity 的实例变量未在 AsyncTask 的 onPostExecute 中设置或如何将数据从 AsyncTask 返回到主 UI 线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆