Android - 在AsyncTask完成后在MainActivity中执行某些操作

时间:2014-05-08 12:46:34

标签: android http asp.net-web-api android-asynctask get

我有一个AsyncTask class会做HttpGet-request。我希望在完成此AsyncTask之后执行某些操作,但是在我的MainActivity内。

这是我的TaskGetAPI class

public class TaskGetAPI extends AsyncTask<String, Void, String>
{
    private TextView output;
    private Controller controller;

    public TaskGetAPI(TextView output){
        this.output = output;
    }

    @Override
    protected String doInBackground(String... urls){
        String response = "";
        for(String url : urls){
            HttpGet get = new HttpGet(url);
            try{
                // Send the GET-request
                HttpResponse execute = MainActivity.HttpClient.execute(get);

                // Get the response of the GET-request
                InputStream content = execute.getEntity().getContent();
                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                String s = "";
                while((s = buffer.readLine()) != null)
                    response += s;

                content.close();
                buffer.close();
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result){
        if(!Config.LOCALHOST)
            output.setText(result);
        else
            controller = Controller.fromJson(result);
    }

    public Controller getController(){
        return controller;
    }

以下是我MainActivity使用此类的方法:

private void sendGetRequest(){
        ...

        // Web API GET-request
        if(!get_url.equals("") && get_url != null){
            TaskGetAPI task = new TaskGetAPI(output);
            task.execute(new String[] { get_url });

            // TODO: When AsyncTask is done, do:
            controller = task.getController();
            Log.i("CONTROLLER", controller.toString());
        }
    }

如您所见,我设置了稍后在Controller的{​​{1}}中使用的onPostExecute-method

因为这反驳了AsyncTask的全部目的,我首先考虑删除Async tasks,然后只做一个普通的课程&amp;我extends AsyncTask的方法,然后我得到HttpGet,这意味着我需要使用android.os.NetworkOnMainThreadException(或类似的东西)来使用AsyncTask来自不同的HttpGet比我的thread

那么,有谁知道我应该在MainThread放些什么?

我尝试使用// TODOboolean field (isDone)课程添加TaskGetAPI,然后使用:

getter

但接下来会发生以下步骤:

    while(true){ if(task.isDone()){ Controller controller = task.getController(); Log.i("CONTROLLER", controller.toString()); } } 课程的
  1. doInBackground已完成。
  2. 现在我们陷入了这个TaskGetAPI ..
  3. 永远不会调用将while(true)-loop设置为onPostExecute

    isDone

3 个答案:

答案 0 :(得分:2)

当任务完成后,它将调用onPostExecute,因此您可以使用LocalBroadcast将广播消息发送到主活动。您可以使用sendBroadcast,它使用异步方式,即一次向所有侦听器发送广播,而不是sendOrderedBroadcast。

答案 1 :(得分:1)

您可以使用响应从onPostExecute发送包含结果的广播。活动将监听它并执行您想要的代码。

而(true)永远不是一个好主意,特别是在电池寿命很重要的手机上。

答案 2 :(得分:0)

假设您只在活动中使用TaskGetAPI,您可以将TaskGetAPI定义为内部类,例如https://developer.android.com/guide/components/processes-and-threads.html#AsyncTask

中的示例
public class MainActivity extends Activity {

    public class TaskGetAPI extends AsyncTask<String, Void, String> {
        /*
         * This object is instanced inside the MainActivity instance,
         * so it has access to MainActivity methods and members
         * (including private ones).
         * Remember to only access to UI elements like views from the main thread,
         * that is, only from onPreExecute, onProgress or onPostExecute
         * In this class "this" makes reference to the TaskGetAPI instance,
         * if you need a refeence to the MainActivity instance, use MainActivity.this
         * 
         */

        protected String doInBackground(String... urls){ ... }

        protected void onPostExecute(String result){
            mMyTextView.setText(result);
        }
    }

    private TextView mMyTextView;
    public void onCreate(Bundle savedInstanceState) {

        setContentView(R.layout.main);
        mMyTextView = (TextView) findViewById(R.id.view);

        new TaskGetAPI().exec();
    }

}

如果需要使用TaskGetAPI,可以在MainActivity之外定义它,并将子类定义为MainActivity的内部类。

还有其他选择,比如定义侦听器(如onClickListeners)并在onPostExecute中调用它们,但这是不必要的复杂。