Android技术点记录-Service

  Service是Android四大组件之一,与Activity很相似。

一、Service基础

1、Service与Activity比较

      相同点:

                  都具有生命周期的概念;

                  需要继承相应的父类(Activity extends Activity;Service extends Service)

                  需要在AndroidManifest.xml中进行配置,且都能通过intent-filter进行过滤

                  都是从Context派生而来

      不同点:

                  service没有界面,一直在后台运行

2、创建配置Service的基本套路

        开发Service总体来说需要两个步骤:

                a、定义一个继承Service的子类

                b、在AndroidManifest.xml中配置该Service

3、Service生命周期方法介绍

         IBinder onBind(Intent intent):该方法是Service子类必须实现的方法。方法返回一个IBinder对象,程序可以通过该对象与Service进行通信。

        void onCreate():当该Service第一次被创建后将立即回调该方法。

        void onDestroy():当该Service被关闭之前将回调该方法。

        void onStartCommand(Intent intent,int flags,int startId):每次客户端调用startService(Intent)方法启动该Service时都会回调该方法。

        boolean onUnbind(Intent intent): 当该Service上绑定的所有客户端都断开连接时将会回调该方法。

4、Service的启动和停止

        Android中运行Service有两种方式:

         a、通过Context的startService(Intent)启动,通过该方法启动Service,访问者与Service之间没有关联,即使访问者退出了,Service仍然运行。

               第一次调用startService(Intent)时,会回调Service的onCreate()方法,之后再次调用startService(Intent)时,onCreate()方法不执行,但是每次都会执行onStartCommand(Intent intent,int flags,int startId);通过startService()启动的Service,必须通过stopService()来停止。不论之前调用了几次start,调用一次stop即可。

         b、通过Context的bindService()启动,通过该方法启动Service,访问者与Service绑定在一起,访问者一旦退出,Service也就终止(此处应该注意,不同的activity调用多次bindService()时,需要所有的activity都退出后,Service才会终止)。

              同一个activity多次调用bindService()绑定同一个Service时,onBind()方法只被回调一次。

              调用unbindService()解除绑定。

              绑定方式时,可以实现组件与Service的交互。

5、Service的生命周期                       

该图描述了启动Service的两种方式以及它们的生命周期。service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。另外一个参考图片,如下:

 

 

二、Service应用

      1、基本应用

            a、start方式:  

                     

1、定义Service,重写父类方法
public class MyService extends Service{
    Override   onCreate,onStartCommand,onDestroy
}
2、activity中调用start
public class MyserviceActivity extends Activity{
     ...
     Intent intent=new Intent(this,MyService.class);
     startService(intent);
     ...
}
3、AndroidManifest.xml中配置service
<service android:name="com.example.service.MyService" > </service>

          

            b、bind方式:

                 如果Service和访问者之间需要进行方法调用或者数据交换,应该使用bindService()和unbindService()方法启动、关闭Service。

                bindService的完整方法签名:bindService(Intent service,ServiceConnection conn,int flags),参数解释如下:

                service:通过Intent指定需要启动的service

                conn:ServiceConnection对象,用于监听访问者与Service之间的连接情况。成功绑定时,将回调其onServiceConnected();service所在的宿主进程由于异常或其他原因终止,导致service与访问者之间的连接断开时,回调其onServiceDisconnected()。其中,主动unbind时,onServiceDisconnected()不被执行。

                flags: 指定绑定时如果service还未创建,是否自动创建Service。0,不自动创建;BIND_AUTO_CREATE,自动创建。

              Service类的IBinder onBinde(Intent intent)方法,在绑定本地service时,返回的IBinder对象将会传给ServiceConnection对象的onServiceConnected(ComponentName name,IBinder service)方法的service参数,这样访问者就可以通过IBinder对象与service进行通信。通常,在开发中,采用继承Binder的方式实现自己的IBinder对象。

 

1、实现自定义Binder,可以在Service实现类中采取内部类的方式实现
     public class MyBinder extends Binder {
	public int getCount() {
	    return count;
        }
     }
2、实现Service,定义成员变量Binder,并在onBinder中返回。
   public class MyService extends Service {
    private MyBinder binder = new MyBinder();
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return binder;
	}
    }
3、activity中定义ServiceConnection,并在onServiceConnected()中获取onBind()返回的Binder实例,用于方法调用或数据获取。
   public class MyserviceActivity extends Activity{
          private MyService.MyBinder service;//用于bind时,activity与service进行通信
            private ServiceConnection conn=new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			Log.i(tag, "service disconnnect");
		}
		/*
		 * IBinder对象可以实现与service的通信
		 */
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			Log.i(tag, "service connect");
			MyserviceActivity.this.service=(MyService.MyBinder)service;
		}
	};
}

 

      2、IntentService应用

               IntentService是Service的子类,比普通Service增加了额外的功能。

               Service本身存在如下两个问题:

                    Service不会专门启动单独的一个进程,与应用处于同一个进程;

                    Service不是专门的一个新的线程,不应该在Service中执行耗时任务,否则会出ANR。

               IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。

              IntentService具有如下特征:

                  创建单独的线程处理所有Intent请求;

                  创建单独的线程处理onHandleIntent()方法实现的代码;

                  处理完所有请求后,IntentService会自动停止;

                  onBind()方法提供了默认实现,默认返回null;

                  onStartCommand()方法提供了默认实现,将intent插入到工作队列中;

补充说明:

Android中的Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。

那么我们当我们编写的耗时逻辑,不得不被service来管理的时候,就需要引入IntentService,IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去你执行你的耗时操作。

应用场景:

         在Android开发中,我们或许会碰到这么一种业务需求,一项任务分成几个子任务,子任务按顺序先后执行,子任务全部执行完后,这项任务才算成功。那么,利用几个子线程顺序执行是可以达到这个目的的,但是每个线程必须去手动控制,而且得在一个子线程执行完后,再开启另一个子线程。或者,全部放到一个线程中让其顺序执行。这样都可以做到,但是,如果这是一个后台任务,就得放到Service里面,由于Service和Activity是同级的,所以,要执行耗时任务,就得在Service里面开子线程来执行。那么,有没有一种简单的方法来处理这个过程呢,答案就是IntentService。

      3、跨进程应用

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值