Service的两种启动方式:startService()与bindService()
statService:生命周期:【onCreate()- >onStartCommand()->startService()->onDestroy()】,与调用者无关可后台运行。
bindService:生命周期:【onCreate()->onBind()->onUnbind()->onDestroy()】,依存于调用的activity。
1.statService启动方式使用(启动的Activity finish后service仍在执行,需stopService()才会停止);
(1)在androidmanifast文件中增加service组件,与activity同一层次下
(2)编写一个类继承Service类,重写onCreate(),onDestroy(),onStartCommand()方法
(3)activity中调用startService(Intent service);启动服务
stopService(Intent service);停止服务
适用于在应用程序被关闭后仍然需要执行的操作;
2.bindService Binder式service(绑定的activity finish后service即刻停止):
bindService使用步骤:
Intent service =new Intent(this,ServiceClass.class);
bindService(Intent service,ServiceConnection conn, int flags);
(1)ServiceConnection对象:用于在activity与service之间建立连接,服务启动后可通过其回调方法使用service中的服务。
ServiceConnection conn=new ServiceConnection(){
//service与Activity建立连接后调用的两个方法,用于使用service中的服务 @Override public void onServiceDisconnected(ComponentName arg0) { // TODO Auto-generated method stub } @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { //arg1为OnBind()方法中返回的Binder对象, 可通过该对象获得service对象本身(在Binder类中有一个getService()方法用于返回service对象本身) MyBinder binder=(MyBinder)arg1; //调用getService()方法获得service对象本身 BindService bindservice=binder.getService(); //接下来便可调用service中的方法来实现一定功能 String result=bindservice.service(); } };
(2)继承Service,重写onCreate(),onBind(),onUnbind(),onDestroy()。
onCreate():在服务第一次创建的时候调用
onBind():在服务在每次启动时调用
onUnBind():在服务停止时调用
onDestory():在服务销毁时调用
service与activity是通过一个Binder(Binder为IBinder子类)子类对象建立联系的,所以要想使用Service子类中的服务操作需要在子类的onBind()方法中返回一个Binder的子类对象,通过该Binder子类对象中的getService()方法来获取Service子类对象本身,这样就可以使用Service子类对象中的各种服务方法了。
class BindService extends Service { // 实现onBind()方法返回一个Binder对象 public IBinder onBind(Intent arg0){ return mybinder; } //内部类Mybinder class MyBinder extends Binder{ public BindService getService(){ return BindeService.this; } } //BindService中的方法,将使用binder.getService().service()调用 public String service(){ // 方法实现 } }
3、IntentService
由于Service中的代码都是运行在主线程中的,如果在Service中处理一些耗时操作,会容易出现ANR的情况。此时需要在Service中开启一个子线程来处理耗时操作。但是会出现忘记开启线程或线程中操作执行完成后忘记停止服务的情况。
所以Android系统提供了一种更为简便的处理Service中ANR情况的方式——使用IntentService。
IntentService有以下特点:
(1) 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
(2) 创建了一个工作队列,来逐个发送intent给onHandleIntent()。
(3) 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
(4) 默认实现的onBind()返回null
(5) 默认实现的onStartCommand()的目的是将intent插入到工作队列中
继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent(Intent intent)函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。
onHandleIntent(Intent intent)中的Intent参数是startService(Intent intent)/bindService(Intent intent)中传进的intent对象,该intent对象可以携带一些参数
在onHandleIntent(Intent intent)方法中可以通过intent携带的参数来区分不同的intent(即如果多次启动同一个service要执行不同操作时可在intent对象中传入不同的参数来区别),接下来便可以执行不同的操作。
//Operation 1 Intent startServiceIntent = new Intent("com.test.intentservice"); Bundle bundle = new Bundle(); bundle.putString("param", "oper1"); startServiceIntent.putExtras(bundle); startService(startServiceIntent); //Operation 2 Intent startServiceIntent2 = new Intent("com.test.intentservice"); Bundle bundle2 = new Bundle(); bundle2.putString("param", "oper2"); startServiceIntent2.putExtras(bundle2); startService(startServiceIntent2);
public class IntentServiceDemo extends IntentService { public IntentServiceDemo() { //必须实现父类的构造方法 super("IntentServiceDemo"); } @Override public IBinder onBind(Intent intent) { System.out.println("onBind"); return super.onBind(intent); } @Override public void onCreate() { System.out.println("onCreate"); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { System.out.println("onStart"); super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override protected void onHandleIntent(Intent intent) { //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务 String action = intent.getExtras().getString("param"); if (action.equals("oper1")) { System.out.println("Operation1"); }else if (action.equals("oper2")) { System.out.println("Operation2"); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onDestroy() { System.out.println("onDestroy"); super.onDestroy(); } }