【问题标题】:How can i know when the async task has returned我怎么知道异步任务何时返回
【发布时间】:2013-12-05 13:29:57
【问题描述】:

我有一个从服务器加载图像 url 的异步任务。加载 url 后,我通过另一个异步任务一个一个地加载图像。 单击一个按钮,我启动第一个异步任务

    public void getit(View v)
    {

        new getdata().execute("http://10.0.2.2/geturls.php");
// line no 2
    }

获得网址后,我使用另一个异步任务来加载图像。 我怎样才能知道图像 url 何时加载,我可以在第 2 行调用第二个异步任务。 如果我使用我在 onpostexecute 中切换的布尔变量

 @Override
            protected void onPostExecute() {
urlgot=true;
}

然后我将不得不在第 2 行的 getit 方法中使用一些重复循环来检查此变量 urlgot 的状态。但它可能需要比 ui 线程允许的更多时间。 有没有更清洁的方法来做这个检查。 谢谢

【问题讨论】:

  • 您是否使用列表视图来处理您的图像?或者他们只是一个 imageView ?如果您使用的是 listView,您可以在您的适配器中使用一次 asyncTask 并为其自动设置位置。

标签: android


【解决方案1】:

我能想到的解决方案有两种:

1) 您创建一个 AsyncTask 来完成所有工作(获取 url,并下载所有图像)。比您确切知道何时开始下载图像。

2) 你从第一个 AsyncTask 的 onPostExecute() 开始下一个 AsyncTask。

【讨论】:

  • 从设计的角度来看,最好有一个 Manager 类来处理下载,当截止日期真的很紧时,我会使用你的第二个选项,但这只会让我在下次更新时遇到麻烦 :)
  • 这取决于项目的大小。但是,是的,创建一个处理后台工作本身的图像管理器将是完美的解决方案。
【解决方案2】:

如果不违背 AsyncTask 的目的,您将无法在 //line no 2 中完成您的下一项工作。如果您正在进行网络活动,则需要异步进行,所以这不是一个选择。

相反,在onPostExecute() 中,您可以在您的活动中调用另一个方法来完成您在//line no 2 中所做的事情。这是安全的,因为onPostExecute() 发生在 UI 线程上。

但根据您的设计,在 onPostExecute 中执行原始 AysncTask 中的所有 //line no 2 内容可能更有意义,因此您只需一项任务即可完成所有工作。

【讨论】:

    【解决方案3】:

    您可以创建interface,将其传递给AsyncTask(在构造函数中),然后调用onPostExecute中的方法

    例如:

    你的界面:

    public interface OnTaskCompleted{
        void onTaskCompleted();
    }
    

    您的活动:

    public YourActivity implements OnTaskCompleted{
        //your Activity
    }
    

    还有你的 AsyncTask:

    public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
        private OnTaskCompleted listener;
    
        public YourTask(OnTaskCompleted listener){
            this.listener=listener;
        }
    
        //required methods
    
        protected void onPostExecute(Object o){
            //your stuff
            listener.onTaskCompleted();
        }
    }
    

    【讨论】:

    • 这不是必须的。该回调已经存在,它是 onPostExecute()。该方法在 UI 线程上执行。
    • @JeffreyKlardie 是的,回调存在,但该接口仅用于传递调用 ASyncTask 的对象的引用。我用这种方式,+1 这不应该被否决
    【解决方案4】:

    使用Handler。在 AsyncTask 的 onPostExecute 方法中,您可以发送一条消息,通知 Handler 启动另一个 AsyncTask。

    类似这样的:

    @Override
        protected void onPostExecute(Void res) {            
    
            MyHandlerHandler handler = new MyHandlerHandler();
            Message msg = new Message();
            msg.what = MyHandler.TASK_FINISHED;
            handler.sendMessage(msg);
        }
    

    在你的 Handler 类中:

    public class MyHandlerHandler extends Handler {
                public static final int TASK_FINISHED = 2;
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
    
            case TASK_FINISHED:
                new MyAsyncTask().execute();
                break;
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      不要将第 2 行放在 getIt 中,而是将其放在 onPostExecute 中,如下所示:

      public void getit(View v)
      
          {
              new getdata().execute("http://10.0.2.2/geturls.php");
          }
      
      
      
         @Override
          protected void onPostExecute() {
            // line 2 
         }
      

      【讨论】:

        【解决方案6】:

        我使用自定义接口在执行后做一些事情。

        public Interface OnDataReceived
        {
            public void onReceive( Object result);
        }
        

        在 MyASyncTask 上

        public class MyAsyncTask extends ASyncTask<Object,Object,Object>
        {
            OnDataReceived receiver;
            public MyAsyncTask( OnDataReceived receiver )
            {
                this.receiver  = receiver;
            }
        ...
            protected void onPostExecute( Object result)
            {
                receiver.onreceive( result );
            }
        }
        

        让我的主类实现 OnDataReceived

        public class Main implements OnDataReceived 
        {
        ....
            public void getit(View v)
            {
                new MyAsyncTask(this).execute("http://10.0.2.2/geturls.php");
            }
            @override
            public void onReceive( Object result)
            {
                // do whatever
            }
        }
        

        编辑

        即使是为了获得更多控制,您也可以添加 onFailed 并将您的界面重命名为 OnResponse

        public Interface OnResponse
        {
            public void onReceive( Object result);
            public void onFailed( Object errcode);
        }
        

        【讨论】:

          猜你喜欢
          • 2019-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-11
          • 2016-08-07
          • 1970-01-01
          • 1970-01-01
          • 2013-04-16
          相关资源
          最近更新 更多