活动的实例变量不onPostExecute被设置的AsyncTask或如何从AsyncTask的数据返回到主UI线程线程、变量、实例、数据

2023-09-06 23:25:53 作者:。怪咖叔叔

我试图找出正确的方式来创建的AsyncTask检索来自互联网的一些数据,然后把这些数据并在意向捆绑起来,并把它传递给新的活动(列表显示)。所以在第一个活动我只是有一个EditText和Button。在一个onClick的事件的任务应该调用和完成时的数据应被捆绑的意图内,并传递到下一个活动。问题是当我从on​​PostExecute结果并将其设置为主要活动的一个实​​例变量,该实例变量仍空当任务完成。这里是code的准系统版本:

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全部结果的应用程序,所以为什么执行任务后,实例变量的地方设置为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的是,根据定义,在不同的线程执行。因此,你不能期望的结果是可以立刻调用执行后。相反,你应该触发新的意图落的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();
        }

}
 
精彩推荐