自己的app的service总是容易被系统回收,搜罗了一下,基本上的解决思路有以下几种:
1.把service写成系统服务,将不会被回收(未实践):
在Manifest.xml文件中设置persistent属性为true,则可使该服务免受out-of-memory killer的影响。但是这种做法一定要谨慎,系统服务太多将严重影响系统的整体运行效率。
2.提高service的优先级(未实践):
设置android:priority="1000"
<!-- 为了消去加上android:priority="1000"后出现的警告信息,可以设置android:exported属性,指示该服务是否能够被其他应用程序组件调用或跟它交互 -->
<service android:name="com.example.helloandroid.weatherforecast.service.UpdateWidgetService" android:exported="false" >
<!-- 为防止Service被系统回收,可以通过提高优先级解决,1000是最高优先级,数字越小,优先级越低 -->
<intent-filter android:priority="1000"></intent-filter>
</service>
3.将服务写成前台服务foreground service(已实践,很大程度上能解决问题,但不能保证一定不会被杀):
重写onStartCommand方法,使用StartForeground(int,Notification)方法来启动service。
注:前台服务会在状态栏显示一个通知,最典型的应用就是音乐播放器,只要在播放状态下,就算休眠也不会被杀,如果不想显示通知,只要把参数里的int设为0即可。
Notification notification = new Notification(R.drawable.logo,
"wf update service is running",
System.currentTimeMillis());
pintent=PendingIntent.getService(this, 0, intent, 0);
notification.setLatestEventInfo(this, "WF Update Service",
"wf update service is running!", pintent);
//让该service前台运行,避免手机休眠时系统自动杀掉该服务
//如果 id 为 0 ,那么状态栏的 notification 将不会显示。
startForeground(startId, notification);
同时,对于通过startForeground启动的service,onDestory方法中需要通过stopForeground(true)来取消前台运行状态。
ps:如果service被杀后下次重启出错,可能是此时重发的Intent为null的缘故,可以通过修改onStartCommand方法的返回值来解决:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
//if this service's process is killed, then it will be scheduled for a restart and the last delivered Intent re-delivered to it again
return Service.START_REDELIVER_INTENT;
4.利用ANDROID的系统广播检查Service的运行状态,如果被杀掉,就再起来(未实践):
利用的系统广播是Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,如果已经被结束了,就重新启动Service。
具体的实现,可以参考这个链接:
http://mobile.51cto.com/abased-374969.htm
补充:以上是解决service容易被回收的方法,但是再进一步深究,为什么service会被系统杀掉呢?通过分析手机的logcat日志发现这么一段话:
引用
06-19 08:01:32.755 W/ActivityManager( 2081): Killing ProcessRecord{43a96570 6437:com.example.helloandroid/u0a187}: background ANR
06-19 08:01:32.910 I/ActivityManager( 2081): Process com.example.helloandroid (pid 6437) (adj 0) has died.
看来这个ANR(Application Not Responding)是关键。上网查到的解释是:
在如下情况下,Android会报出ANR错误:
– 主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件
– BroadcastReceiver 没有在10秒内完成返回
通常情况下,下面这些做法会导致ANR
1、在主线程内进行网络操作
2、在主线程内进行一些缓慢的磁盘操作(例如执行没有优化过的SQL查询)
主线程中执行过多的操作也是不好的,我的主线程里有访问网络的处理,于是想办法将网络访问移出主线程,通常有两种方法:把访问网络放在独立线程或者异步线程AsyncTask中。至于具体怎么实现,google之。
分享到:
相关推荐
Service启动后,即使用户离开应用程序,它也会继续运行,直到手动停止或被系统回收。Service有两种启动方式:startService()和bindService()。前者启动Service后,Service会持续运行直到stopSelf()或stopService()被...
- `onDestroy()`: 当系统需要回收资源或者用户手动停止Service时,此方法会被调用,表示Service即将被销毁。 2. **bindService()启动模式** 使用`bindService()`启动Service时,Service的生命周期与客户端绑定的...
Android系统会尽可能保持Service运行,即使用户已经切换到其他应用或关闭了应用的UI。Service可以通过startService()或bindService()方法启动,两者有不同的生命周期和使用场景。 在这个场景中,Service可能会被...
然而,如果主进程被系统回收,本地服务也将随之终止,例如HTC的音乐播放服务和天天动听就是本地服务的例子。 远程服务则独立于主进程,拥有自己的进程名,通常是包名加上指定的`android:process`字符串。远程服务的...
当系统资源紧张时,Android可能会停止服务以回收资源,但你需要在`onStartCommand()`返回适当的标志来指示服务如何响应。例如,返回`START_STICKY`表示服务被杀死后,系统会重新启动它。 在`PlayService`中,你可能...
默认情况下,Service 被标记为 background,而设置为 foreground 后,其优先级将与正在运行的 Activity 类似,从而降低被系统回收的可能性。 #### 六、通过其他方式启动 Service 除了从 Activity 中启动 Service ...
当Service被销毁时,系统会回收与之相关的所有资源。 ### 绑定Activity和Service 除了通过startService()方法启动服务之外,还可以通过绑定Activity与Service来实现它们之间的通信。在这种情况下,通常使用onBind...
- `onDestroy()`: 当调用`stopService()`或系统需要回收资源时,Service将被销毁。 如果Service尚未运行,`onCreate()`和`onStartCommand()`会被依次调用。如果Service已经在运行,只会调用`onStartCommand()`。...
- `onDestroy()`: 当调用`stopService()`或系统需要回收资源时,Service会被销毁。 如果Service尚未运行,`onCreate()`和`onStartCommand()`都会被调用。如果Service已经在运行,只会调用`onStartCommand()`。...
Service是Android系统中的一个重要组件,它是用来在后台执行长时间运行任务而不会被用户界面直接交互的。在Android开发中,Service常用于实现如播放音乐、网络通信等需要长时间运行的功能,即使用户离开应用,...
通过调用`startForeground()`方法,Service可以在通知栏显示一个通知,这样Service就会被赋予更高的优先级,更不容易被系统回收。不过,这也意味着需要始终向用户显示服务正在运行的通知。 在多线程方面,Service...
同时,Service的运行会消耗系统资源,因此,长时间运行的Service可能会被系统回收,特别是在设备资源紧张时。为优化Service的使用,可以考虑使用IntentService,这是一种预设了工作线程并自动停止的Service子类,...
// 返回服务的启动模式,这里选择START_STICKY,即使服务被系统回收,也会尝试重新启动 return START_STICKY; } ``` 3. **定义Binder**(可选): 如果你需要与Service进行交互(例如控制播放、暂停等),可以...
然而,由于Android系统的资源管理策略,Service可能会在系统需要回收内存时被杀死。为了确保某些关键服务能够持续运行,开发者需要采取措施来保证Service不被轻易终止。以下是一些关键知识点和策略: 1. **Service...
4. `onDestroy()`: 当Service被停止或系统需要回收资源时调用,用于释放资源和清理工作。 在`MediaPlayerService`中,我们可以创建一个`startMusic()`方法来启动音乐播放,并在`stopMusic()`方法中停止。这些方法...
7. **处理生命周期事件**: 当用户结束播放或者系统需要回收资源时,需要在`onDestroy()`方法中释放资源,如关闭音乐播放器,解除与Service的绑定等。 8. **权限申请**: 如果音乐来自网络,可能需要在...
- **AndroidService**:指的是运行在System Server进程中的系统服务,例如Activity Manager Service、Package Manager Service等。这些服务为整个系统提供了关键功能,是构建在Dalvik VM之上的组件,通过JNI调用底层...
《Android 4.0.1系统源码深度解析》 Android 4.0.1,代号冰淇淋三明治(Ice Cream Sandwich),是Google推出的一个重要版本,它为Android操作系统带来了许多新特性和改进。系统源码是理解Android运行机制的关键,...
然而,系统在资源紧张时可能会停止Service以回收资源,因此,开发者应确保Service在不再需要时自行终止,以减少对系统的影响。 此外,Service可以通过`Binder`对象提供与客户端(如Activity)的交互,通过实现`...
Android系统源代码是开发者深入了解Android系统运行机制、优化应用性能、解决技术难题的关键所在。这份源代码包含了Android系统的四层架构:应用程序层、应用程序框架层、系统库层和Linux内核层。下面将详细探讨这四...