【问题标题】:AsyncTask, Handler, Thread... Which one to choose [duplicate]AsyncTask,Handler,Thread ...选择哪一个[重复]
【发布时间】:2014-05-21 00:38:36
【问题描述】:

我知道这个问题已被问过很多次,但我得到的所有答案都不清楚。

我想实现一个文件删除过程。我发现要完成这种工作,建议在一个单独的线程中运行所有进程。

为此,我可以使用AsyncTaskHandlerThreadAsyncTask 似乎是一个很好的解决方案。然而,AsyncTask 是为小任务而设计的。 (当我尝试删除长度超过 1G 的文件时,AsyncTask 崩溃或不执行 onPostExecute

其他线程处理程序(ThreadRunnable...)无法管理 UI(更新 UI 或显示进度)。

我的问题是什么是长任务的好线程处理程序以及如何使用它管理 UI。

【问题讨论】:

  • 尝试后台服务,从服务中为长任务启动一个新线程,并使用广播接收器与其通信并更新主用户界面。
  • 你的前提不正确。 AsyncTask 正是为您描述的情况而设计的。您没有包含有关您的崩溃的信息,但它是由其他问题引起的。将该问题移至线程不是解决方案。

标签: java android multithreading android-asynctask


【解决方案1】:

首先,如果您需要在主线程之外执行工作,但仅在用户与您的应用交互时,那么您应该创建一个新线程,否则使用服务。

现在,你可以用 AsyncTask 做的所有事情,你也可以用 Thread(+ Handler) 来做。但是 AsyncTask 使开发人员的工作更容易,因为它旨在将工作线程与主线程(调用者线程)进行通信。现在,如果您使用 Hanlder,您还可以将工作线程与调用者线程通信(注意调用者线程不一定是主线程,它可能是两个工作线程之间的通信),如果调用者线程是主线程,你最好使用 AsyncTask。

据我所知,它是这样的:

  • 如果您需要运行与 UI 线程通信的短任务,请使用 AsyncTask
  • 使用 ThreadHandler 运行需要工作线程和主线程(调用者线程)之间通信的较长任务
  • 使用 ThreadHandlerLooper(或 HandlerThread,这是用于启动已有一个 Looper)用于需要工作线程和调用者线程(不是主线程)之间通信的较长任务。
  • IntentService 用于不需要用户交互且只需要一个工作线程的较长任务。

【讨论】:

  • 感谢您的详细回答。我认为 Handler 和 Thread 是运行 Long Tasks 并与 UI Thread 通信的最佳解决方案。我会试试的
  • 我认为这个答案可能有点误导。在极少数情况下,开始自己的线程是个好主意。
  • 你的意思是改用线程池,让Android处理线程?例如使用执行器框架
【解决方案2】:

对我来说最好的是Asynctask,因为结构定义好,你可以知道什么时候运行线程,什么时候显示结果。

【讨论】:

【解决方案3】:

http://masl.cis.gvsu.edu/2010/04/05/android-code-sample-asynchronous-http-connections/

上面关于使用处理程序的好文章。

使用处理程序删除:

创建一个执行三件事的可运行对象:

删除文件

获取消息并发送成功

获取消息并在失败时发送

使用一些框架来管理线程或使用并发包,发布可运行文件,它将在主线程中执行文件Del。处理程序回调将是 msg 成功或 msg 失败,将在主线程 wherview 控制器上处理。

【讨论】:

    【解决方案4】:

    查看 Needle,您可以忘记 Handlers 和 AsyncTasks。 Needle 是一个开源、简单但功能强大的 Android 多线程库。有了它,你可以说:

    Needle.onMainThread().execute(new Runnable() {
        @Override
        public void run() {
            // e.g. change one of the views
        }
    });
    

    Needle.onBackgroundThread().execute(new UiRelatedTask<Integer>() {
        @Override
        protected Integer doWork() {
            int result = 1+2;
            return result;
        }
    
        @Override
        protected void thenDoUiRelatedWork(Integer result) {
            mSomeTextView.setText("result: " + result);
        }
    });
    
    • 非常简单的 API
    • 固定线程池大小
    • 可自定义的线程池大小
    • 支持 UI 交互(“做工作,然后在 UI 线程上使用结果”)
    • 安卓1.5+
    • 在所有平台版本上表现相同

    在 GitHub 上查看:https://github.com/ZsoltSafrany/needle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多