您的位置:首页 > 移动开发 > Android开发

Android四大组件Service 服务

2016-12-17 20:07 363 查看
Android四大组件

•Activity

•BroadcastReceiver 广播接收者

•Service 服务

•ContentProvider 内容提供者

Service的继承关系

public abstract class Service extends ContextWrapper implements ComponentCallbacks2

public class ContextWrapper extends Context

public abstract class Context

Service的编写步骤:

1.写一个类继承 Service

2.重写onBind()方法 

3.在清单文件的下面声明service

服务Service

•服务是没有界面的组件,运行在后台,服务是运行在当前应用程序进程里

服务的应用场景

如果有耗时的操作,不想有界面、而且还不想程序退出就停止运行的逻辑,放在服务里

例如:定时的轮询,消息推送等等

注意:服务也是运行在主线程中,如果有耗时操作,要放在子线程里,如果服务被系统杀死了,会默认重启

如何开启服务

startService(Intent intent);

如何关闭服务

stopService(Intent intent);

生命周期

onCreate() -> onstartcommand() -> onstart() -> onDestroy()

•用start方法开启服务,服务只会被创建一次,执行一次onCreate方法,一旦服务创建完成,后续调用start去开启服务只会执行onstart和onstartcommand方法

•当调用了stop方法,服务只会调用一次onDestroy方法

进程的优先级

•Foreground process 

前台进程:用户正在操作的应用程序进程叫做前台进程

•Visible process 

可视化进程:用户已经不能操作这个应用程序了,但是用户还能看到应用程序界面

•Service process

服务进程:应用程序服务在后台运行

•Background process

后台进程:应用程序界面被用户最小化

•Empty process

空进程:应用程序没有任何的activity和service运行

前台进程 > 可视化进程 > 服务进程 > 后台进程 > 空进程

开启服务的方法

startService();

•不能调用服务里的方法,不可以与服务进行通信

bindService();绑定服务

•可以间接的调用服务里的方法,可以与服务进程通信

绑定服务步骤

1.创建服务类

class MyService extends Service{}

2.定义一个接口,暴露对外提供的方法

public interface IService{
    public void callServiceMethed();

}

3.在服务类里定义代理对象,定义一个方法可以间接的调用服务的方法

private class MyBinder extends Binder implements IService{

   public void callServiceMethed(){
      调用服务的方法

   }

   ...

}

这样写的好处:可以防止不想被暴露的方法被别人调用了

4.在onBinder方法里返回代理对象,如果不返回,调用方拿到的对象就是空的

public IBinder onBind(Intent intent) {
     return new MyBinder();

}

5.创建类实现 ServiceConnection,实现里面的两个方法

private class MyConn implements ServiceConnection{
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //当服务连接成功时候调用
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        //当服务断开连接时调用
    }

 }

6.activity采用绑定的方式开启服务

bindService(intent, new MyConn(),  BIND_AUTO_CREATE);

7.在onServiceConnected方法里强转获取所需要的对象

IService iService = (IService) service;

8.调用代理对象的方法,间接的调用了服务里的方法

开启绑定服务的生命周期

•bindService开启,如果服务不存在,调用 onCreate() -->onBind() ,不会调用 onStart()和onStartCommand()

•unbindService解除绑定,onUnbind() --> onDestroy()

•多次绑定服务,onCreate方法和onBind方法只会执行一次

两种方式开启服务的比较

•直接调用startService开启服务

服务一旦开启,会长时间在后台运行,与开启在不再有关系,

开启在退出了,服务还是在运行的,而且不能调用服务里的方法

•用bindService开启服务

服务开启了是和开启在的生命周期绑定的,如果开启在关闭了,服务也就关闭了,

开启者可以间接的调用服务里的方法

•如果服务同时被开启和绑定,那么服务就停不掉了,需要解除绑定服务才能停止服务

用混合方式开启服务

需要服务长期在后台运行,还需要调用服务里的方法,用混合方式开启服务

严格按照步骤编写代码:

1.start方式开启服务 ->保证服务在后台能够长时间运行

2.bind方式绑定服务 ->绑定了服务,方便调用服务里的方法

3.unBind方式解绑

4.stop方式停止服务

本地服务和远程服务

•本地服务 local service

服务代码在当前应用程序内部

•远程服务 remote service

服务代码在另外的应用程序中

概念

•进程

操作系统分配的独立的内存空间

•IPC

inter process communication 进程间通讯

•aidl

android interface definition language 安卓接口定义语言

绑定远程服务调用服务的流程

和本地服务代码差不多,有几个小细节需要注意

1.远程服务定义的接口文件不能是.java文件,需要改成.aidl文件,里面的修饰符都不需要

2.原来的代理对象继承对象需要改变

private class MyBinder extends Binder implements IService 

--> 

private class MyBinder extends IService.Stub

3.把远程服务的.aidl文件拷贝到本地工程,包名需要和远程服务的包名一致

4.获取代理对象的方法需要改变

IService iService = (IService) service; 

--> 

IService iService = IService.Stub.asInterface(service);

5.通过代理对象调用远程服务方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: