Java 异步任务太慢,无法同时执行多个网络操作

Java 异步任务太慢,无法同时执行多个网络操作,java,android,android-asynctask,Java,Android,Android Asynctask,我正在开发一个必须与服务器进行大量交互的应用程序。因此,用户输入名称和密码,授权后,必须执行以下任务: 应用程序必须获取此用户的所有传入和传出消息,并将它们加载到SQLite数据库 获取所有用户好友(带有id、姓名、联系人数据的JSON),并将其加载到应用程序的数据库中 跳转到下一个活动并显示来自本地数据库的收入消息。 此操作速度太慢,当应用程序启动新活动时,无法从数据库中获取任何内容:AsyncTasks尚未完成。我被迫使用AsyncTask.get()等待它们全部完成,但等待时间超过16秒

我正在开发一个必须与服务器进行大量交互的应用程序。因此,用户输入名称和密码,授权后,必须执行以下任务:

  • 应用程序必须获取此用户的所有传入和传出消息,并将它们加载到SQLite数据库
  • 获取所有用户好友(带有id、姓名、联系人数据的JSON),并将其加载到应用程序的数据库中
  • 跳转到下一个活动并显示来自本地数据库的收入消息。 此操作速度太慢,当应用程序启动新活动时,无法从数据库中获取任何内容:AsyncTasks尚未完成。我被迫使用AsyncTask.get()等待它们全部完成,但等待时间超过16秒 所以,我应该怎么做:使用线程,或者在将提取的数据加载到数据库之前,将其保存在内存中并在新活动中显示,而不是从数据库中提取数据?但是,即使没有数据库任务,其他提取任务也要等待近10秒!那我该怎么办

  • 你应该使用服务。这样,它总是可以完成它正在做的任务,您也可以完成您的所有任务。此外,你应该初始化应用程序一次,然后只更新数据。。那不可能需要10秒钟。。而不是你有另一个问题。。但这项服务的好处是它可以在后台运行。见:

    ==编辑


    还可以看看这个库如何安排快速SQlLite操作。没有大的设置

    异步任务并不意味着同时运行多个小任务。引用

    首次引入时,异步任务是在单个后台线程上串行执行的。从DONUT开始,它被更改为一个线程池,允许多个任务并行运行。从蜂巢开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误

    如果要同时运行多个任务,请在
    ThreadPool
    中使用
    Thread
    s

    你想如何处理这种情况取决于你自己。当后台任务花费的时间太长时,您可以始终向用户显示警报对话框,然后在填充数据后将其带到活动。发生这种情况时,许多应用程序都会显示“加载”屏幕。如果还没有可用数据,还可以显示“加载”微调器控件。永远不要显示空白屏幕


    如果服务器端调用由您控制,请使用某种缓存来加快时间。任何持续超过一秒钟的API调用都会让用户变得不耐烦。如果没有,请使用上一段中提到的技术之一@如果你能做到的话,感知技术也是一种考虑。

    OK这里有两件事情非常错误。
  • 不要将异步任务用于联网。使用服务。简而言之,这是因为一旦启动异步任务的活动停止,它就会停止。这意味着网络请求很容易中止,数据丢失,并且在再次打开活动时必须重新启动

  • 不要在异步任务上使用.get()。这使得UI线程等待任务完成,使得整个AsyncTask想法变得毫无用处。换句话说:这会阻塞您的UI

  • 你应该做什么:

  • 了解如何使用服务。您还可以查看一个名为RoboSpice的优秀开源库来帮助您实现这一点

  • 停止在异步任务上使用.get(),如果您想知道它何时完成,只需使用侦听器即可

  • 尽可能在线程池(myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);)上执行异步任务


  • 当其他操作仍在后台运行时,您是否考虑过快速获取要显示给用户的信息?这是许多移动应用程序为了增加低延迟的外观而使用的一种策略。执行一项任务需要多少时间?有多少任务是并行执行的?@DeepakBala有7个任务,我使用.get()来完成所有任务…@Perception请你详细解释一下这个问题好吗?@HarryCater每个任务平均需要多少时间?“10秒”是平均时间吗?这是完全错误的。根据谷歌的说法:“如果你需要在主线程之外执行工作,但只在用户与应用程序交互时执行,那么你可能应该创建一个新线程,而不是一个服务。”在这种情况下,服务不会给他买任何东西,因为它们仍然在应用程序主线程上运行。看@LeifAshley,我不认为是。你忽略了“工作”和网络之间的区别。如果你读了下面这句话,你会看到:“例如,如果你想播放一些音乐,但只能在你的活动正在进行时播放”。这里有两个重要的区别需要注意:播放音乐不是网络;以及“当您的活动正在运行时”。仅仅因为他没有上传任何数据,并不意味着每当活动被销毁时,如果所有的网络进度都丢失了,那么就可以了。@LeifAshley注意到,一个活动不仅在用户离开应用程序或当前屏幕时被销毁,而且在每个示例中,如果他旋转设备时也会被销毁。当使用AsyncTask拉入数据时,您的应用程序必须重新启动,导致加载时间延长。即使用户出于某种原因决定离开你的应用程序,你也可能希望完成网络请求。你应该研究一下使用SyncAdapter(它也运行一项服务,建议用于与服务器双向同步数据)或RoboSpice之类的库处理相同数据的优点。@LeifAshley当然,他必须在服务中创建一个线程,但这是一个完全不同的主题。你说“不要将异步任务用于联网。使用服务。”根据