第六章后台服务Service项目任务:通过学习Android相关历史及开发环境的搭建,完成第一个简单应用程序的设计与开发,并理解Android项目中各个文件及目录的功能。项目要求:掌握Android开发环境的搭建方法在Eclipse软件上设计并运行自己的第一个程序了解Android项目的结构及各个文件的功能掌握Android系统四大组件的基本功能6.1后台服务Service简介服务(Service)是Android系统中4个应用程序组件之一,主要用于两个目的:后台运行和跨进程访问。通过启动一个服务,可以在不显示界面的前提下在后台运行指定的任务,这样可以不影响用户做其他事情。通过服务也可以实现不同进程之间的通信,这也是服务的重要用途之一。在实际应用中,有很多应用需要使用Service,一般使用Service为应用程序提供一些服务,或不需要界面的功能,例如,从Internet下载文件、控制Video播放器等,经常提到的例子就是MP3播放器要求在切换播放器界面进入电子书阅读界面后,仍旧能保持音乐的正常播放,这就需要在Service中实现音乐播放功能。6.1后台服务Service简介Service并没有实际界面,而是一直在Android系统的后台运行,这一点是和前面章节学习的Activity有着极大的差别,Activity必然是有界面的,能和用户进行交互的。因此Service无需用户干预,但需较长时间运行的功能场合。没有用户界面,意味着降低了系统资源的消耗,而且Service具有比Activity更高的优先级,因此在系统资源紧张的情况下,Service不会轻易被Android系统终止,即使Service被系统主动终止,在系统资源恢复后,Service也将自动恢复运行状态,因此可以认为Service是在系统中永久运行的组件。这一点从另外一个方面提醒开发者,在程序中要正确把握好自己开发的后台服务Service生命周期。Service与Activity除了以上的差别外,使用起来比较类似,下面就一些关键点进行比较:使用Service需要继承Android.App.Service类,并在AndroidManifest.xml文件中使用service标签声明,否则不能使用,这一点和Activity一样。实现Service只需Java源文件实现功能,无需xml描述的Layout布局文件。启动Service的方法和启动Activity方法相同,都有显示启动和隐式启动两种方式,如果服务和调用服务的组件在同一个应用中,两种方法都可行,如果服务和调用服务的组件不在相同的应用程序中,则只能使用隐式启动。6.1后台服务Service简介6.1后台服务Service简介Service也有一个从启动到销毁的过程,但Service的生命周期过程比Activity简单得多,Service启动到销毁的过程一般经历3个阶段:创建服务;开始服务;销毁服务。一个服务实际上是一个继承了Android.App.Service的类,当服务经历上面3个阶段时,会分别调用Service类中的3个事件方法进行交互,这3个事件方法如下:1.publicvoidonCreate();//创建服务2.publicvoidonStartcommend();//开始服务,替代了原有onStart()方法3.publicvoidonDestroy();//销毁服务一个服务只会创建一次,销毁一次,但可以开始多次,因此,onCreate()和onDestroy()方法只会被调用一次,而onStartcommend()方法可以被调用多次。Service的使用方式有两种,一种为启动方式,一种为绑定方式。第一种启动方法即在需启动服务的Activity中使用StartService()方法来进行方法的调用,调用者和服务之间没有联系,即使调用者退出了,服务依然在进行,调用顺序为onCreate()→onStartCommand()→startService()→onDestroy()。6.2服务Service的两种使用方式当其他组件(比如一个Activity)通过Context.startService()方法启动Service时,系统会创建一个Service对象,并顺序调用onCreate()方法和onStartCommand()方法。在调用Context.stopService()或者stopSelf()之前,Service一直处于运行的状态。这里需要强调的是,如果Service已经启动了,当再次启动Service时,不会在执行onCreate()方法,而是直接执行onStartCommand()方法,同样的道理,无论调用了多少次stopService(),只需要调用一次stopService()就可以停止Service。Service对象在销毁之前,onDestroy()会被调用,因此与资源释放相关的工作应该在此方法中完成。6.2服务Service的两种使用方式第二种是在相关Activity中使用bindService()方法来绑定服务,调用者和绑定者绑在一起,调用者一旦退出服务也就终止了,执行顺序为onCreate()→onBind()→onUnbind()→onDestroy。调用Context.bindService()启动方式时,客户端可以绑定到正在运行的Service上,如果此时Service没有运行,系统会调用onCreate()方法来创建Service,Service的onCreate方法只会被调用一次。如果已经绑定了,那么启动的时候就直接运行Service的onStartcommand()方法,如果先启动,那么绑定的时候就直接运行onBind方法。如果先绑定上了,就停止不了,也就是stopService不能用了,只能先unbindService,再stopService,所以,先启动还是先绑定,是有区别的。6.2服务Service的两种使用方式客户端成功绑定到Service之后,可以从onBind()方法中返回一个IBinder对象,并使用IBinder对象来调用Service的方法。一旦客户端与Service绑定,就意味着客户端和Service之间建立了一个连接,只要还有连接存在,那么系统会一直让Service运行下去。下面通过两个例程分别来说明服务的两种使用方法。6.2服务Service的两种使用方式6.2.1使用StartService()方法使用服务项目StartServiceModeDemo项目结构如图6-1所示,源程序中分别有一个Activity和Service对应的Java文件,Activity的对应界面如图6-2所示,只有一个TextView和两个Button,布局文件为main.xml。通过Activity中的启动Service按钮使用StartService()方法进行启动服务,服务的功能是产生一个随机整数(0~100之间)并通过Toast方式进行显示。通过停止Service按钮使用StopService()方法停止该后台服务。6.2服务Service的两种使用方式项目实现过程如下:在Eclipse中新建项目,名称为StartServiceModeDemo。实现本项目的一个Activity和对应的布局文件,即StartServiceModeActivity.java,对应布局文件为main.xml,如图6-2所示。实现StartServiceModeService.java代码,继承自Service类,Override4个主要的方法。修改AndroidManifest.xml文件,增加前两步所实现的Activity和Service的声明。调试和运行项目如下。6.2服务Service的两种使用方式6.2服务Service的两种使用方式图6-1服务启动项目结构图图6-2服务启动项目界面图现在对关键代码段进行分析,首先看StartServiceModeActivity.java这个文件的关键代码。1publicclassStartServiceModeActivityextendsActivity{2/**Calledwhentheactivityisfirstcreated.*/3@Override4publicvoidonCreate(BundlesavedInstanceState){5super.onCreate(savedInstanceState);6setContentView(R.layout.main);7ButtonstartButton=(Button)findViewById(R.id.start);8ButtonstopButton=(Button)findViewById(R.id.stop);9//定义显示启动所需要的Intent对象,和显示启动Activity类似10finalIntentserviceIntent=newIntent(this,StartServiceModeService.class);11//第一个按钮的监听事件,实现启动服务功能12startButton.setOnClickListener(newButton.OnClickListener(){13publicvoidonClick(Viewview){14startService(serviceIntent);15}16});6.2服务Service的两种使用方式17//第二个按钮的监听事件,实现停止服务功能18stopButton.setOnClickListener(newButton.OnClickListener(){19publicvoidonClick(Viewview){20//系统会自动调用服务的生命周期函数停止服务21stopService(serviceIntent);22}23});24}25}6.2服务Service的两种使用方式本段代码首先表明继承了Activity类,并重写了onCreate()方法,在此实现了全部功能。第7~8行代码分别生成两个Button变量,并和布局文件中的按钮id进行了关联。第10行代码是关键,定义了显示启动所需要的Intent对象,分别在第14行和21行代码被调用,分别实现了启动服务和关闭服务的功能。第12~16行代码实现了启动按钮的动作监听功能,当点击该按钮时,设置的监听器setOnClickListener()会执行onClick()方法中的内容,这里就14行一句代码,将需启动Service的Intent传递给startService(Intent)函数即可实现启动服务。第18~23行代码实现了停止按钮的动作监听功能,当点击该按钮时,设置的监听器setOnClickListener()会执行onClick()方法中的内容,这里就21行一句代码,停止服务。6.2服务Service的两种使用方式然后看一下StartServiceModeService.java这个文件的关键代码。1publicclassStartServiceModeServiceextendsService{23@Override//第一次调用StartService()时会调用本方法,即实现初始化功能4publicvoidonCreate(){5super.onCreate();6Toast.makeText(this,(1)调用onCreate()方法,初始化服务,7Toast.LENGTH_LONG).show();8}910@Override//每次StartService()调用时都会调用本方法,所以具体功能代码一定在这里实现11publicintonStartCommand(Intentintent,intflags,intstartId){12Toast.makeText(this,(2)调用onStartCommand()方法,实现服