Service: 生命周期与 startService

Service 经常被使用,结合开发过程中遇到的问题以及注意事项,总结一下 android service 组件。


Service: 小试 AIDL IPC 牛刀 是我年少轻狂之时写的一篇很糟糕的博文,那个时候学得东西不多,但是激情很高。


本来想删掉它,然后重新写一篇,以免毒害他人。后来,还是舍不得,略做修改,勉强一下吧!


本人觉得,it 就是一份扯淡的事业。只要你在 it 行业,就会永远发现新东西。没有尽头!


学会分享和总结,你会发现世界还是很美好地!


这篇博文,算是很简单的入门,高手或者你已经很清楚 service 生命周期的不妨试读一下,给点建议。


运行界面




点击 Button 会启动一个Service(PlayerService),Activity(PlayerActivity)代码示例如下

[java]  view plain copy print ?
  1. package mark.zhang;  
  2.   
  3.   
  4. import android.app.Activity;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8.   
  9.   
  10. public class PlayerActivity extends Activity {  
  11.   
  12.   
  13. @Override  
  14. public void onCreate(Bundle savedInstanceState) {  
  15.     super.onCreate(savedInstanceState);  
  16.     setContentView(R.layout.main);  
  17. }  
  18.   
  19.   
  20. public void onService(View view) {  
  21.     Intent intent = new Intent(PlayerActivity.this, PlayerService.class);  
  22.     startService(intent);  
  23. }  
  24.   
  25. }  


PlayerService 代码示例如下

说明:onStart 方法已经过时了,所以使用 onStartCommand 方法。


[java]  view plain copy print ?
  1. package mark.zhang;  
  2.   
  3.   
  4. import android.app.Service;  
  5. import android.content.Intent;  
  6. import android.os.Handler;  
  7. import android.os.IBinder;  
  8. import android.util.Log;  
  9.   
  10.   
  11. public class PlayerService extends Service {  
  12. private static final String TAG = "PlayerService";  
  13.   
  14.   
  15. private static final long DELAY = 5000;  
  16.   
  17.   
  18. private int mServiceStartId = -1;  
  19.   
  20.   
  21. private Handler sWork = new Handler();  
  22.   
  23.   
  24. private Runnable task = new Runnable() {  
  25.   
  26.   
  27.     @Override  
  28.     public void run() {  
  29.         Log.d(TAG, DELAY / 1000 + "s after-----------");  
  30.         stopSelf();  
  31.         //stopSelf(mServiceStartId);  
  32.     }  
  33. };  
  34.   
  35.   
  36. @Override  
  37. public IBinder onBind(Intent intent) {  
  38.     Log.d(TAG, "onBind------");  
  39.     return null;  
  40. }  
  41.   
  42.   
  43. @Override  
  44. public void onCreate() {  
  45.     super.onCreate();  
  46.     Log.d(TAG, "onCreate------");  
  47.     sWork.postDelayed(task, 5000);  
  48. }  
  49.   
  50.   
  51. @Override  
  52. public int onStartCommand(Intent intent, int flags, int startId) {  
  53.     Log.d(TAG, "onStartCommand------and startId = " + startId);  
  54.     mServiceStartId = startId;  
  55.     return super.onStartCommand(intent, flags, startId);  
  56. }  
  57.   
  58.   
  59. @Override  
  60. public void onDestroy() {  
  61.     Log.d(TAG, "onDestroy------");  
  62.     super.onDestroy();  
  63. }  
  64.   
  65. }  


在 PlayerService 里面使用 Handler 在 5s 之后停止 PlayerService。


点击 Button 5 次,打印结果




5s 之后,调用 stopSelf(实际调用的是 stopSelf(-1) 这个方法),停止服务。


当然,你也可以在 PlayerActivity 里面调用 stopService 来停止服务。


从这里,可以看出通过 startService 启动服务,其生命周期是这样的。


                                                         



在 Service 的一个生命周期中,onCreate / onDestroy 方法只调用一次,onStartConmand 方法可以被调用多次。

在 onStartConmand 方法里面,可以看出,每调用一次这个方法,startId 就会加 1.


stopSelf() 与 stopSelf(int startId) 与 stopService 的s功效是一样的。

网上很多人说,stopSelf() 与 stopSelf(int startId) 是不会立即停止服务的,我觉得说法不科学。


调用 stopSelf() 或者 stopSelf(int startId),  这个时候 onDestroy 均会被调用,说明 service 的生命已经 over,哪来的服务没有停止?只能说应用程序没有停止,你写的代码如线程死循环一直在跑,虽然该线程也是在 service 里面启动的,但是记住 Service 是与 Activity 默认在一个进程(一个 application 就是一个进程),那麽应用程序没有挂掉,死循环的线程怎么会停止?!


下面举个例子:


在 PlayerService 的 onStartCommand 方法里面


isRunning 是成员变量,默认值为 false

[java]  view plain copy print ?
  1. @Override  
  2. public int onStartCommand(Intent intent, int flags, int startId) {  
  3.     Log.d(TAG, "onStartCommand------and startId = " + startId);  
  4.     mServiceStartId = startId;  
  5.   
  6.     isRunning = true;  
  7.   
  8.     new Thread(new Runnable() {  
  9.   
  10.         @Override  
  11.         public void run() {  
  12.             while(isRunning) {  
  13.                 Log.d(TAG, "running--------------------");  
  14.             }  
  15.         }  
  16.        }).start();  
  17.   
  18.     return super.onStartCommand(intent, flags, startId);  
  19. }  

       

可见如果 isRunning 不设置为 false 或者该 Application 不停止,这个该死的线程永远也不会停下来。

所以,需要在合适的地方设置 isRunning 


如 onDestroy


[java]  view plain copy print ?
  1. @Override  
  2. public void onDestroy() {  
  3.     Log.d("mark""onDestroy------");  
  4.     isRunning = false;  
  5.     super.onDestroy();  
  6. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值