服务service

服务时后台运行,没有界面

一、进程的概念

当一个应用启动后,后台会生成这个应用的进程,这个进程(process)中包含应用的主线程(Thread);

进程的优先级

1、Foreground process 前台进程,用户正在使用的应用,相当于activity处于onResume优先级最高

2、Visible process 可视进程,一直影响用户可见状态,相当于activity的onPause方法

3、Service process 服务进程,服务被启动,服务调用startService()方法

4、Background process 后台进程,应用不可见,相当于activity处于onStop()状态,界面不可见未执行onDestory()方法

5、Empty process 空进程,应用不维护任何可激活的组件属于空进程,但系统不会直接杀死这个种进程,为了缓存的作用,方便下次使用的开启效率。系统会杀死这种进程来维持系统性能的稳定。

二、服务

【1】配置清单文件

android:name="com.example.birdtest.TestService">

【2】定义服务,继承Service类

public class MyService extends Service {

@Override

public void onCreate() {

服务创建

super.onCreate();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

服务开启

return super.onStartCommand(intent, flags, startId);

}

@Override

public void onDestroy() {

服务销毁

super.onDestroy();

}

【3】服务使用

1)在Activity中开启服务

Intent intent = new Intent(this,MyService.class)

2)startService(intent);

在Activity中关闭服务

Intent intent = new Intent(this.MyService.class);

stopService(intent);

【4】特点

1)第一次开启服务,服务执行onCreate()方法和onStartCommond()方法

2)再次开启服务时,服务仅执行onStartCommond()方法;

3)服务一旦被开启,服务就会在后台长期运行,直到用户手动停止

三、电话监听器

TelephonyManager:电话的服务管理者,可以获取电话的状态和电话的其他信息

实例化:

TelephonyManager tm = Context.getSystemService(Context.TELEPHONY_SERVICE);

录音机:MediaRecorder

实现代码:

/**

* 电话监听器

*/

public class PhoneyService extends Service {

//录音机实例

MediaRecorder mr = null;

@Override

public void onCreate() {

//【1】获取电话监听服务

TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

//【2】注册电话监听状态

//参数1 具体时那个类去接听,写监听的逻辑;参数2 常量 监听电话的状态

tm.listen(new MyPhoneStatListen(),PhoneStateListener.LISTEN_CALL_STATE);

super.onCreate();

}

//定义一个类监听电话的状态

public class MyPhoneStatListen extends PhoneStateListener{

//电话状态发生改变时调用

@Override

public void onCallStateChanged(int state, String phoneNumber) {

//【3】判断电话的状态

switch (state){

case TelephonyManager.CALL_STATE_IDLE: //电话空闲状态

if(mr!=null){

mr.stop();

mr.reset();

mr.release();

}

break;

case TelephonyManager.CALL_STATE_OFFHOOK : //电话的摘机的状态(接听)

//开始录音

mr.start();

break;

case TelephonyManager.CALL_STATE_RINGING: //电话响铃状态

//准备录音机MediaRecorder

//[1]创建

mr = new MediaRecorder();

//[2]设置音频的来源mic 麦克 Voice_call 双方的通话麦克和听筒

mr.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);

//[3]设置音频输入格式 3gp格式

mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

//[4]设置音频的编码方式

mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

//[5]设置文件存储的位置

mr.setOutputFile("");

//[6]准备录音

try {

mr.prepare();

} catch (IOException e) {

e.printStackTrace();

}

//下面的步骤放入

//[7]开始录音

//mr.start();

//[8]停止录音

//mr.stop();

//[9]重置

//mr.reset();

//[10]释放资源

//mr.release();

break;

//[11]配置权限

//

}

super.onCallStateChanged(state, phoneNumber);

}

}

四、启动服务的两种方式

1、startService(); 直接开启;

2、bind方式开启服务;

【1】定义服务

public class TestService extends Service {

//中介,让Activity可以调用doServiceDoSomething方法

public class MyIBinder extends Binder {

public void callService(){

doServiceDoSomething();

}

}

//当服务绑定时调用,服务只能绑定一次

@Override

public IBinder onBind(Intent intent) {

return new MyIBinder();

}

public void doServiceDoSomething(){

System.out.println("服务做的事情");

}

}

【2】调用绑定的服务

Intent service = new Intent(MainActivity.this,TestService.class);

myServiceConnection = new MyServiceConnection();

//意图,定义的服务,服务自动创建

bindService(service,myServiceConnection,BIND_AUTO_CREATE);

myIBinder.callService();

//这个类用于监听服务的状态

public class MyServiceConnection implements ServiceConnection{

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

myIBinder = (TestService.MyIBinder) service;

//可以调用服务的方法了

myIBinder.callService();

System.out.println("服务调用成功");

}

@Override

public void onServiceDisconnected(ComponentName name) {

System.out.println("失去服务的链接");

}

}

【3】注意:

当Activity被销毁时注意解绑服务

unbindService(MyServiceConnection);

1)第一次执行时,服务会执行OnCreate()和OnBind();

2)当OnBind()方法返回为null时,OnServiceConnected()方法不执行

3)多次绑定服务没有相应

4)服务不可以多次解绑

5)绑定的服务在设置页面中没有显示,相当于隐形的服务

7)绑定的服务可以在activity中调用服务里的方法

6)Activity挂掉的时候,服务也会挂掉。

3、混合开启服务-固定步骤

【1】先调用startService方法开启服务,确保服务能在后台长期运行

【2】调用bindService方法,获取中间人对象

【3】调用unbindService方法,解绑服务

【4】调用stopService()方法

五、调用服务的方法

【1】通过bindservice方式调用服务方法的过程

1)在服务中定义一个方法,让Activity调用

public void myMedhod(int pro){

doSomething();

}

2)在服务的内部定义一个中间人对象

public class MyBind extends Binder{

public void callMethod(int pro){

myMethod(pro);

}

}

3)服务中返回中间人对象

public IBinder onBind(Intent intent){

return new MyBind();

}

4)在Activity中绑定服务

Intent intent = new Intent(this,MyService.class);

Myconn conn = new Myconn();

bindService(intent,conn,BIND_AUTO_CREATE);

5)重写onDestroy(),解绑服务 unbindService(conn);

6) Activity中拿到中间人对象myBinder,就可以调用服务的方法了。

private class Myconn implements ServiceConnection{

//重新服务调用成功的方法

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

myIBinder = (TestService.MyIBinder) service;

System.out.println("服务调用成功");

}

//重写服务失去链接的方法

}

【2】通过接口的方式调用服务李的方法

java的多态

1)定义一个接口,把服务中的方法暴露出来

2)定义的中间人对象实现定义的接口

3)在activity中获取中间人对象时的类型时我们定义的接口

六、aidl

全称 Android Interface Definition Language ,Android接口定义语言

本地服务:运行在自己应用里的服务

远程服务:运行在其他应用里的服务

实现进程中的通信, IPC,Inter-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。

实现步骤

【1】被调用者创建aidl文件,这个文件类似于java的接口文件

【2】系统会自动生成这个aidl文件的类 Iservice.aidl

public static abstract class Stub extends IBinder implements Iservice

【2】被调用者使用onBinder()获取的IBinder对象 需要的IBinder 继承Stub

【3】被调用者配置清单文件



//调用者需要通过这个来调用

【3】保证调用和被调用的两个aidl文件是同一个,保证aidl文件的包名和类名相同

【4】调用者获取IBinder对象通过Stub中的静态asInterface()方法

public void onServiceConnected(ComponentName name,IBinder service){

iservice = Stub.asInterface(service);

}

【5】调用者使用

Intent intent = new Intent();

intent.setAction("com.ncs.myservice");//被调用者服务应以的包名

//绑定服务

bindService(intent,ServiceConnection,BIND_AUTO_CREATE);

【6】注意调用远程服务捕获异常