Service启动方式之startService

  • Service概念及用途:

    A service is an application component that can perform long-running operations in the background and does not provide a user interface。

    通常service用来执行一些耗时操作,或者后台执行不提供用户交互界面的操作,例如:下载、播放音乐。

    Service生命周期 :

    Android Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法,具体的可以看下面的实例。

    Service与Activity通信:

    Service后端的数据最终还是要呈现在前端Activity之上的,因为启动Service时,系统会重新开启一个新的进程,这就涉及到不同进程间通信的问题了(AIDL)这一节我不作过多描述,当我们想获取启动的Service实例时,我们可以用到bindService和onBindService方法,它们分别执行了Service中IBinder()和onUnbind()方法。


    这里要提及一点:继承service的子类在重写service的方法中,除了一个onStart()方法之外,还有一个onStartCommand()方法,有关onStartCommand()方法稍微作点介绍:

    Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值,这篇文章就是简单地讲讲int返回值的作用。
    从Android官方文档中,我们知道onStartCommand有4种返回值:

    START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
    START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统将会把它置为started状态,系统不会自动重启该服务,直到startService(Intent intent)方法再次被调用;。
    START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
    START_STICKY_COMPATIBILITY: START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

    有了 Service 类我们如何启动他呢,有两种方法:

          • Context.startService() 
          • Context.bindService()


         1.  在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。

          2. 另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。

    区别概况为:
        startService() 的调用者与服务没有联系,即使调用者退出了,服务仍然运行,而bindService() 的调用者与服务绑在一起,调用者一旦退出了,服务也随即终止掉。

    这里用一个实例(使用 startService()方法来启动)来讲解一下service的声明周期和使用方法:

    首先编写一个类继承Service这个基类,重写里面的方法,然后在Activity中调用 startService()和stopService()来启动和停止服务。

    运行界面:



    工程目录结构:



    ExampleService.Java

    [html]  view plain  copy
     print ?
    1. package com.service.activity;  
    2.   
    3. import android.app.Service;  
    4. import android.content.Intent;  
    5. import android.os.IBinder;  
    6. import android.util.Log;  
    7.   
    8. public class ExampleService extends Service{  
    9.     private static final String TAG = "ExampleService";   
    10.   
    11.     @Override  
    12.     public void onCreate() {  
    13.         Log.i(TAG, "ExampleService-onCreate");  
    14.         super.onCreate();  
    15.     }  
    16.   
    17.     @Override  
    18.     public void onStart(Intent intent, int startId) {  
    19.         Log.i(TAG, "ExampleService-onStart");  
    20.         super.onStart(intent, startId);  
    21.     }  
    22.   
    23.     @Override  
    24.     public int onStartCommand(Intent intent, int flags, int startId) {  
    25.         //执行文件的下载或者播放等操作  
    26.         Log.i(TAG, "ExampleService-onStartCommand");  
    27.         /*  
    28.          * 这里返回状态有三个值,分别是:  
    29.          * 1、START_STICKY:当服务进程在运行时被杀死,系统将会把它置为started状态,但是不保存其传递的Intent对象,之后,系统会尝试重新创建服务;  
    30.          * 2、START_NOT_STICKY:当服务进程在运行时被杀死,并且没有新的Intent对象传递过来的话,系统将会把它置为started状态,  
    31.          *   但是系统不会重新创建服务,直到startService(Intent intent)方法再次被调用;  
    32.          * 3、START_REDELIVER_INTENT:当服务进程在运行时被杀死,它将会在隔一段时间后自动创建,并且最后一个传递的Intent对象将会再次传递过来。  
    33.          */  
    34.         return super.onStartCommand(intent, flags, startId);  
    35.     }  
    36.   
    37.     @Override  
    38.     public IBinder onBind(Intent intent) {  
    39.         Log.i(TAG, "ExampleService-onBind");  
    40.         return null;  
    41.     }  
    42.       
    43.     @Override  
    44.     public void onDestroy() {  
    45.         Log.i(TAG, "ExampleService-onDestroy");  
    46.         super.onDestroy();  
    47.     }  
    48.   
    49. }  

    MainActivity.java

    [html]  view plain  copy
     print ?
    1. package com.service.activity;  
    2.   
    3. import android.app.Activity;  
    4. import android.content.Intent;  
    5. import android.os.Bundle;  
    6. import android.view.View;  
    7. import android.view.View.OnClickListener;  
    8. import android.widget.Button;  
    9.   
    10. public class MainActivity extends Activity implements OnClickListener{  
    11.     private static final String TAG = "MainActivity";   //日志输出标志  
    12.     private Button btnStartService;  
    13.     private Button btnStopService;  
    14.       
    15.     @Override  
    16.     public void onCreate(Bundle savedInstanceState) {  
    17.         super.onCreate(savedInstanceState);  
    18.         setContentView(R.layout.main);  
    19.         btnStartService = (Button)findViewById(R.id.btnStartService);  
    20.         btnStopService = (Button)findViewById(R.id.btnStopService);  
    21.         btnStartService.setOnClickListener(this);  
    22.         btnStopService.setOnClickListener(this);  
    23.     }  
    24.     //点击事件处理监听器  
    25.     @Override  
    26.     public void onClick(View v) {  
    27.         Intent intent = new Intent(MainActivity.this,ExampleService.class);  
    28.         switch(v.getId()){  
    29.         case R.id.btnStartService:  
    30.             startService(intent);  
    31.             break;  
    32.         case R.id.btnStopService:  
    33.             stopService(intent);  
    34.             break;  
    35.         default:  
    36.             break;  
    37.         }  
    38.     }  
    39. }  


    最后在AndroidManifest.xml中对service进行声明,它跟Activity同一级,都写在Application标签里面:

    <service android:name=".ExampleService"/>


    创建完运行


    在运行点击"启动service"之后(第一次启动service),我们可以查看LogCat控制台输出的日志如下:


    这个时候我们点击"返回",Activity被干掉了,但是我们的服务仍然在运行,可以查看Setting-->Application-->Running Service,截图如下:



    然后回到我们的Activity,再次点击启动Service,控制台输出日志如下:


    onCreate()方法没有被调用,说明它并没有重新被创建。

    然后我们点击停止Service,输出日志如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值