Android线程和服务停止,恕不另行通知

时间:2014-05-23 12:56:07

标签: android multithreading android-service

所以我做了一个使用大量线程的应用程序/ Runnable(我们正在谈论300多个)来下载大量内容。这在模拟器和一些设备(如三星Galaxy S3)上工作正常但由于某些原因在HTC One和其他设备上我的线程或服务被停止而没有任何通知,警告,错误。应用程序继续运行,但启动所有线程的任何服务/线程都被终止。

我尝试过的事情:

  • 使用ExecutorService(线程池)启动和管理所有线程
  • 使用ExecutorService
  • 启动AsyncTask中的线程
  • 使用ExecutorService启动绑定服务中的线程
  • 在服务START_STICKY和startForeground
  • 中启动线程

来自HTC One的Logcat与START_STICKY和startForeground(刚刚保存的数据称为POI,开始下载26号然后停止):

05-23 14:52:54.732: D/libc(17514): [NET] getaddrinfo+,hn 13(0x6170692e706172),sn(),family 0,flags 4
05-23 14:52:54.732: D/libc(17514): [NET] getaddrinfo-,err=8
05-23 14:52:55.363: D/historie(17514): save POI id: jtyvZD9bX9
05-23 14:52:55.383: D/historie(17514): Starting poi number: 26
05-23 14:52:57.595: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:52:57.595: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 1, mLinkspeedSum: 72
05-23 14:52:59.998: D/PMS(705): acquireWL(4237bc08): PARTIAL_WAKE_LOCK  AlarmManager 0x1 705 1000
05-23 14:53:00.028: D/PMS(705): releaseWL(4237bc08): PARTIAL_WAKE_LOCK  AlarmManager 0x1
05-23 14:53:00.048: I/ClockThread(996): now=1400849580059 next=59941
05-23 14:53:00.068: W/MastheadClock(1546): mDigitAnimMin.start
05-23 14:53:00.608: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:00.608: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 2, mLinkspeedSum: 144
05-23 14:53:03.642: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:03.642: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 3, mLinkspeedSum: 216
05-23 14:53:06.675: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -64 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:06.675: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 4, mLinkspeedSum: 288
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -64 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 5, mLinkspeedSum: 360
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative: Update RSSI:-64 and linkspeed:72 in database
05-23 14:53:09.698: D/WifiApDatabaseHandler(705): updateConnectedAP...

修改1

因此,手动调用GC使我能够下载更多数据,然后再次停止,所以每次下载新数据时都可以通过调用GC来解决它。这是我目前的实现,但为什么完成的线程会占用内存?有没有更好的方法呢?

3 个答案:

答案 0 :(得分:1)

可能是您正在达到Android系统可以处理的线程数量的限制。 你提到你使用ExecutorService。默认情况下,只有 5 主题可以同时运行限制 128 主题可以排队。

查看AsyncTask的源代码 CORE_POOL_SIZE 是可以同时运行的任务数, MAXIMUM_POOL_SIZE 是可以排队的线程数。

答案 1 :(得分:1)

运行GC永远不是解决方案!它只是表明代码实现不好。

您没有提供代码,但是从您描述的方案中,您会在系统中溢出对象和数据,这就是您需要不时地调用GC的原因。

确保您重复使用对象,例如。 - 即使您使用的是threadPool - 您是否重用了runnables或者只是为每个线程创建一个新的runnable?

如果您使用Task作为示例,请确保取消并清除其TimerTask。清除将清除所有已结束的任务,

由于只有2个线程同步存在,因此线程并发不会产生该问题。

答案 2 :(得分:0)

我最终使用的解决方案在没有崩溃或停止的情况下运行:

System.gc();
startNewThreadAction();

这有效,但主要的问题是我不得不用这么多线程来讨论。如果您可以在许多线程和大量数据之间进行选择,那就可以获得大量数据。