浅析Android(安卓)Service 中 onStartCommand方法及注意事项
文章目录
- 1、Service 的生命周期
- 2、onStartCommand方法
- onStartComand的返回值
- 3、使用注意事项
1、Service 的生命周期
以调用startService()为例,上图中onCreate方法仅在startSercice()调用后运行一次;然后运行onStartCommand(); onDestory ()仅在stopService()或stopSelf()方法调用后执行一次。
那么在这期间,如果service被系统kill掉,那么会重新调用onStartCommand()来重新运行。
2、onStartCommand方法
onStartComand的返回值
这个整形可以有四个返回值:start_sticky、start_no_sticky、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
它们的含义分别是:
-
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后一定能重启。
###onStartCommand参数flags含义
flags表示启动服务的方式:
Additional data about this start request. Currently either 0, START_FLAG_REDELIVERY, or START_FLAG_RETRY.
- START_FLAG_REDELIVERY: 如果你实现onStartCommand()来安排异步工作或者在另一个线程中工作, 那么你可能需要使用START_FLAG_REDELIVERY来 让系统重新发送一个intent。这样如果你的服务在处理它的时候被Kill掉, Intent不会丢失.
- START_FLAG_RETRY:表示服务之前被设为START_STICKY,则会被传入这个标记
3、使用注意事项
由于onStartCommand会被重复调用,因此在onStartCommand中申请了资源或添加了Window,然后在onDestory中释放的逻辑是不成立的,因为系统异常kill掉service不会调用onDestory,而重复调用onStartCommand方法又会在上次资源或window没有释放的情况下重新申请,这样就会产生无法预估的错误。
如下代码,我在onStartCommand中添加了Window,在onDestory中进行了释放,就遇到了Service启动后被异常kill掉的情况,结果就同时出现了多个窗口导致无法操作。因此需要在window添加处进行判空处理,保证服务可以重启,但window只能有一个。
@Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub if (mWindowManager == null) { ... mWindowManager = (WindowManager) getApplicationContext() .getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.type = (WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW + 22); layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; mView = View.inflate(getApplicationContext(),R.layout.manager_layout, null); mWindowManager.addView(mView, layoutParams); ... }
更多相关文章
- tcping测试服务器TCP端口
- Android中的MVP笔记之四: Data Binding 库的使用之数据绑定是否是
- Android(安卓)手机灭屏流程分析详解
- Android中ListView数据使用sAdapter.notifyDataSetChanged();方
- Android设置PreferenceCategory背景颜色的方法
- android如何得到控件大小 OnGlobalLayoutListener
- Android(安卓)6.0事件分发机制源码解析
- Android(安卓)Socket服务器 Servlet服务器
- Android点击事件分发流程