Service表示服务。是Android系统的核心组件之中的一个。
Service的本质是一个继承了android.app.Service的java类;
每个Service都应该在AndroidMainfest.xml文件里进行注冊;
Service由Android系统进行维护。
Service没有匹配的用户界面,通经常使用于后台处理耗时操作。
不同意在主线程中运行耗时操作。
Service是执行在主线程中的;
虽然Service被定位为“用于处理耗时操作”。可是各种耗时操作须要在Service中另外开辟线程来完毕。
组件能够绑定到Service,实现进程间通信(Inter Process Communication)。
进程优先级:
Android系统力图维护尽可能多的线程,但因为设备性能有限。在动态管理内存的过程中。Android系统
会常常可以终止一些优先级低的进程。以释放资源,保证优先级高的进程正常执行。
进程优先级分类:
1、前台进程(Forground Process)
2、可见进程(Visible Process)
3、服务进程(Service Process)
4、后台进程(BackGround Process)
5、空进程(Empty Process)
启动Service
开发者能够使用Intent激活Service组件。
激活Service组件的方式有:
调用Context定义的startService()方法(启动)
调用Context定义的bindService()方法(绑定)
启动Service的开发流程
启动Service的开发流程例如以下:
1、创建java类。继承android.app.Service;(Service中定义了抽象方法onBlind(),该方法必须被重写。但不一定须要被详细实现)
2、在AndroidMainfest.xml中的<application>下加入<service>子节点,
配置创建的Service;
3、在Activity中调用startService(Intent intent)方法启动Service;
显式或隐式启动Service
不管是显式Intent或隐式Intent都能够激活Service组件。
假设须要实现进程间通信,则应该为Service组件配置隐式意图过滤器。
停止Service
通过调用Context的stopService(Intent intent)方法能够停止Service,并销毁该Service组件。
在Service中调用stopSelf()方法能够停止自身。
Service的生命周期
假设Activity重复调用startService()方法。在Service中仅仅会重复调用onStartCommand()方法。
案例:
<Button android:id="@+id/btn_start" android:layout_width="match_parent" android:layout_height="wrap_parent" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="50dp" android:onClick="doStart" android:text="Start Service"/> <Button android:layout_marginTop="20dp" android:id="@+id/btn_stop" android:layout_width="match_parent" android:layout_height="wrap_parent" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="50dp" android:onClick="doStop" android:text="Start Service"/>
public void doStart(View view){ Intent intent = new Intent(this,SampleService.class); startService(intent); } public void doStop(View view){ Intent intent = new Intent(this,SampleService.class); stopService(intent); }
Service类:
public class SampleService exteds Service{ public void onCreate(){ Log.d(tag,"onCreate") super.onCreate(); } public int onStartCommand(Intent intent,int flags,int startId){ Log.d(tag,"onStartCommand"); return super.onStartCommand(intent,flags,startId); } public void onDestroy(){ Log.d(tag,"onDestroy"); super.onDestroy(); } }
AndroidMainfest.xml
<service android:name="com.edu.hpu.cn.SampleService"></service>
Service的粘性
Service的粘性:Service的粘性表现为其所在进程被意外中止后,该Service能否够自己主动又一次被启动。
默认情况下。使用startService()方式激活的Service组件是粘性的,则即使其所在进程被意外中止了。
稍后该Service依旧会被自己主动创建出来。
设置Service的粘性
在Service生命周期中onStartCommand()方法的返回值决定了Service的粘性。
该方法的返回值能够被设置为:
START_STICKY:粘性的。被意外中止后自己主动重新启动。但丢失原来用于激活它的Intent;
START_NOT_STICKY:非粘性的,被意外中止后不会自己主动重新启动。
START_REDELIVER_INTENT:粘性的且又一次发送Intent。即被意外中止后自己主动重新启动,且该Service
组件将得到原来用于激活它的Intent对象。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本号,并不担保onStartCommand()会被又一次调用。
案例:
Service播放音乐
使用系统的MediaPlayer类能够播放音乐,开发过程例如以下:
创建MediaPlayer对象,可直接使用无參数构造方法。
调用MediaPlaye的reset()方法重置(不必要);
调用MediaPlayer的setDataSource()方法设置须要播放的歌曲。
调用MediaPlayer的prepare()方法载入(缓冲)歌曲。
调用MediaPlayer的start()方法播放歌曲。
当退出时应该调用release()方法释放资源。
本例的业务逻辑:
通过Activity激活Service,且在Service中创建mediaPlayer的实例,实现歌曲的播放;
被播放的歌曲保存在模拟器的sdcard/Misic/中。
当Activity被停止时,停止播放歌曲的Service。
当Service被停止时,释放MediaPlayer的资源。
案例:
MainActivity:
package com.edu.hpu.service; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void startMusic(View view){ Intent intent = new Intent(this,PlayerMusicService.class); startService(intent); } @Override protected void onDestroy() { // TODO Auto-generated method stub Intent intent = new Intent(this,PlayerMusicService.class); stopService(intent); super.onDestroy(); } }布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="136dp" android:onClick="startMusic" android:text="播放音乐" /> </RelativeLayout>
Service类:
package com.edu.hpu.service; import java.io.IOException; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.Environment; import android.os.IBinder; public class PlayerMusicService extends Service{ private MediaPlayer player; @Override public void onCreate() { try { player = new MediaPlayer(); player.reset(); player.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Music/Groove Coverage - She.mp3"); player.prepare(); player.start(); } catch (IllegalArgumentException e) { // TODO: handle exception e.printStackTrace(); }catch(SecurityException e){ e.printStackTrace(); } catch(IllegalStateException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } @Override public void onDestroy() { // TODO Auto-generated method stub player.release(); player = null; super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
配置:
<service android:name="com.edu.hpu.service.PlayerMusicService"></service>
关于MediaPlayer MediaPlayer支持主流的音频、视频文件的播放。亦支持播放 非本机的媒体文件; MediaPlayer会开启子线程播放歌曲; 可调用pause()方法暂停播放,调用seekTo()方法快进到指定的 位置開始播放; 可调用prepareAsync()方法载入歌曲,并配置OnPreparedListener, 在监听器用调用MediaPlayer的start()方法; 通常为MediaPlayer配置OnCompletionListener,以实如今播放完毕后的处理;