【问题标题】:Start Async Task within a worker thread在工作线程中启动异步任务
【发布时间】:2012-03-19 00:06:33
【问题描述】:

我有两个问题:

  • 我们可以在工作线程中启动/执行异步任务吗?
  • 如果是,则在 UI 线程上调用方法 onPreExecute()onProgressUpdate(Progress...)onPostExecute(Result)

我想知道,因为我有一个在工作线程上运行的 TCP 连接,当收到一个数据包时,我想启动一个新线程来解析这个数据包,然后刷新 UI 线程上的一些数据结构。

提前致谢!

【问题讨论】:

  • 虽然 AsyncTasks 非常适合某些事情,但听起来这个应用程序并不完全是其中之一。作为替代方案,您可以只处理 Thread 类的子类

标签: android multithreading asynchronous task


【解决方案1】:

来自Android AsyncTask doc

“任务实例必须在 UI 线程上创建。”,和

"execute(Params...) 必须在 UI 线程上调用。"

所以我认为你的第一个问题的答案是“不”。至于第二种,这些方法都是在UI线程上调用的,但是有点没有实际意义。

编辑:我不确定这些是绝对限制还是强烈建议,但在这两种情况下,我都建议遵循它们。

【讨论】:

    【解决方案2】:

    仅作记录:如果您在 UI 线程之外启动 AsyncTask,则 onPreExecute 将不会从 UI 线程(而是从调用者线程)执行.这将导致异常。然而 onPostExecute 方法将始终在 UI 线程上执行。希望对某人有所帮助:)

    【讨论】:

      【解决方案3】:

      根据 Android 文档,您必须从 UI 线程运行 AsyncTask,但实际上这取决于谁首先在 AsyncTask.class 中运行此行:

      private static final InternalHandler sHandler = new InternalHandler();
      

      如果您有一个同时从 UI 和工作线程调用的 AsyncTask,则可以通过首先从 UI 线程调用它来绕过此限制。如果您首先从工作线程中击中它,那么您注定要失败。 我宁愿不依赖它,因为实现细节随时可能发生变化,但如果您像我一样想知道“为什么我的其他 AsyncTask 工作”,那么这些知识很有用。

      【讨论】:

        【解决方案4】:

        来自 Android AsyncTask 文档:

        “任务实例必须在 UI 线程上创建。”,和

        "execute(Params...) 必须在 UI 线程上调用。"

        所以,以下是合法的。

        new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // do some work here
        
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    new MyAsyncTask(ctx).execute(); 
                                }
                            });
                        }
                    }).start();
        

        【讨论】:

        • 这毫无意义,所以-1。您正在从主线程启动一个线程,它将运行任务委托给主线程......如果您只运行 new MyAsyncTask(ctx).execute(); 而不是所有无意义的代码,情况也会如此。
        • @Cipi 我猜他只是指出你可以从任何工作线程内部调用runOnUiThread。 (自评论//do some work here
        【解决方案5】:

        简单来说,我们可以在worker中启动AsyncTask。您可以在新线程中执行 AsyncTask,非常简单。 原因在Android源代码中: [clike here]

        private static class InternalHandler extends Handler {
            public InternalHandler() {
                super(Looper.getMainLooper());
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-20
          • 1970-01-01
          • 1970-01-01
          • 2023-03-31
          • 1970-01-01
          相关资源
          最近更新 更多