Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-在异步任务完成后在MainActivity中执行某些操作_Android_Http_Asp.net Web Api_Android Asynctask_Get - Fatal编程技术网

Android-在异步任务完成后在MainActivity中执行某些操作

Android-在异步任务完成后在MainActivity中执行某些操作,android,http,asp.net-web-api,android-asynctask,get,Android,Http,Asp.net Web Api,Android Asynctask,Get,我有一个AsyncTask类,它将执行HttpGet请求。我想在AsyncTask完成后做一些事情,但要在我的main活动中进行 这是我的TaskGetAPI类: public class TaskGetAPI extends AsyncTask<String, Void, String> { private TextView output; private Controller controller; public TaskGetAPI(TextView

我有一个
AsyncTask类
,它将执行
HttpGet请求
。我想在
AsyncTask
完成后做一些事情,但要在我的
main活动中进行

这是我的
TaskGetAPI类

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;
    }
如您所见,我设置了
控制器
,稍后在
异步任务
onPostExecute方法
中使用该控制器

由于这与
异步任务的全部目的背道而驰
我首先想到删除
扩展异步任务
,只是为我的
HttpGet
创建一个常规类和方法,但随后我得到了一个
android.os.networkMainThreadException
,这意味着我需要使用
异步任务
(或类似的东西)从与my
Main线程不同的
线程中使用
HttpGet

那么,有人知道我应该在
//TODO
上写什么吗

我确实尝试使用
getter
布尔字段(isDone)
添加到
TaskGetAPI
类中,然后使用:

while(true){
    if(task.isDone()){
        Controller controller = task.getController();
        Log.i("CONTROLLER", controller.toString());
    }
}
但随后会发生以下步骤:

  • TaskGetAPI
    类的
    doInBackground
    已经完成
  • 现在我们被困在这个
    而(true)-loop

  • 并且将
    isDone
    设置为
    true
    onPostExecute
    永远不会被调用。

    假设您只在活动中使用
    TaskGetAPI
    ,您可以将
    TaskGetAPI
    定义为一个内部类,如中的示例所示

    公共类MainActivity扩展活动{
    公共类TaskGetAPI扩展了AsyncTask{
    /*
    *此对象在MainActivity实例中实例化,
    *因此它可以访问MainActivity方法和成员
    *(包括私人的)。
    *记住只从主线程访问UI元素,如视图,
    *也就是说,只能从onPreExecute、onProgress或onPostExecute执行
    *在这个类中,“this”引用TaskGetAPI实例,
    *如果需要对MainActivity实例的引用,请使用MainActivity.this
    * 
    */
    受保护的字符串doInBackground(字符串…URL){…}
    受保护的void onPostExecute(字符串结果){
    mMyTextView.setText(结果);
    }
    }
    私有文本视图mMyTextView;
    创建时的公共void(Bundle savedInstanceState){
    setContentView(R.layout.main);
    mMyTextView=(TextView)findViewById(R.id.view);
    新建TaskGetAPI().exec();
    }
    }
    
    如果需要使用
    TaskGetAPI
    ,可以在MainActivity外部定义它,并将子类定义为MainActivity的内部类


    尽管还有其他选项,比如定义监听器(比如onClickListeners)并在onPostExecute中调用它们,但这并不必要复杂。

    假设您只在活动中使用
    TaskGetAPI
    ,您可以将
    TaskGetAPI
    定义为一个内部类,如中的示例所示

    公共类MainActivity扩展活动{
    公共类TaskGetAPI扩展了AsyncTask{
    /*
    *此对象在MainActivity实例中实例化,
    *因此它可以访问MainActivity方法和成员
    *(包括私人的)。
    *记住只从主线程访问UI元素,如视图,
    *也就是说,只能从onPreExecute、onProgress或onPostExecute执行
    *在这个类中,“this”引用TaskGetAPI实例,
    *如果需要对MainActivity实例的引用,请使用MainActivity.this
    * 
    */
    受保护的字符串doInBackground(字符串…URL){…}
    受保护的void onPostExecute(字符串结果){
    mMyTextView.setText(结果);
    }
    }
    私有文本视图mMyTextView;
    创建时的公共void(Bundle savedInstanceState){
    setContentView(R.layout.main);
    mMyTextView=(TextView)findViewById(R.id.view);
    新建TaskGetAPI().exec();
    }
    }
    
    如果需要使用
    TaskGetAPI
    ,可以在MainActivity外部定义它,并将子类定义为MainActivity的内部类


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

    您可以通过响应从onPostExecute发送一个包含结果的广播。活动将侦听它并执行所需的代码


    虽然(正确)从来都不是一个好主意,尤其是在电池寿命很重要的手机上。

    您可以从onPostExecute发送一个带有响应的广播结果。活动将侦听它并执行所需的代码


    虽然(true)从来都不是一个好主意,尤其是在电池寿命很重要的手机上。

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

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

    Thnx,使用了类似于此stackoverflow答案中的广播管理器:。Thnx,使用了类似于此stackoverflow答案中的广播管理器:。
    while(true){
        if(task.isDone()){
            Controller controller = task.getController();
            Log.i("CONTROLLER", controller.toString());
        }
    }
    
    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();
        }
    
    }