一、service基本概念:

  1.service是一个可以在后台长时间执行运行操作,而且没有用户界面的应用组件。服务可由其他组件启动,一旦启动将在后台一直运行。即使启动的组件被销毁也不影响。
    不能单独运行在一个进程中,需要依赖所创建服务所在的程序进程;只能在后台运行,并且可以与其他组件进行交互。
  2.应用场所:播放多媒体的时候用户启动了其他Activity,此时要在后台继续播放;比如检测SD卡上文件的变化;比如在后台记录你的地理信息位置的改变等等,总之服务是藏在后台的。
  3.服务不会自动开启线程,需要再内部手动开启线程。
  4.默认情况下一个started的service与启动他的组件是在一个线程中的。

二、服务的两种形式:

  1.启动状态:当应用组件调用startService启动服务的时候,服务即处于‘启动状态‘,服务即可在后台无线运行。即使启动的组件被销毁也不会受影响。除非手动调用才能销毁。

  2.绑定状态:当应用组件通过bindService绑定服务时候,服务即处于‘绑定状态‘,绑定状态服务提供一个客户端服务接口,允许组件与服务进行交互、发送请求、获取结果,利用扩进程通信执行这些操作。
        当与一个应用组件绑定时,绑定组件才会执行,多个组件可以同时绑定这个服务,当所有绑定的组件全部解绑时才会销毁该服务。

三、清单文件注册属性:

  enable:true|false:这个服务是否能被系统实例化。
  exported:true|false:是否其他应用组件能够调用这个service或同他交互,默认值是否包含过滤器。
  icon:服务呈现的图标
  isolatedProcess:true|false:如果设置为true,则这个服务运行在一个专门的进程中
  label:这个服务给用户显示的名称
  permission:String:为了启动这个服务或绑定到它的实体类必须要有的权限名称
  process:String:服务将运行的进程名称

四、定义启动服务

  1.创建一个类,继承android.app.service,实现抽象方法onBind,重写onCreate、onStartCommand、onDestry
  2.清单文件配置service
  3.停止service的两种方式:外部使用stopService;服务内部(onStartCommend方法内部)stopSelf();
  4.onStartCommend()方法返回值:返回一个int型,有三个数值:START_NOT_STICKY、START_STICKY、START_REDELIVER_INTENT;
    START_NOT_STICKY:"非粘性的",服务被异常kill掉之后,系统不会重启该服务。
    START_STICKY:如果service进程被kill掉,保留service为开始状态,但不保留递送的intent对象,系统会尝试重新创建service。由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。
    如果在此期间没有任何启动命令被传递到Service,那么参数Intent将为null。
    START_REDELIVER_INTENT:系统会自动重启该service,并将Intent的值传入。

五、IntentService类:简单创建一个异步、会自动停止的服务。当启动多次时,耗时任务会以工作队列的方式在onHandleService()回调方法中执行。每次只会执行一个工作线程,执行完再执行第二个。

六、Thread和service的关系

  Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,Service既然是运
  行在主线程里,在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。
  既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例;而且在一个Activity中创建的子线程,另一个Activity
  无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例

七、使用Bind service进行通信。

  1.只有activity、service、Content Provider能绑定服务,BroadCastReceiver不能绑定服务。
  2.客户端组件通过bindService能绑定服务,然后android系统会回调服务的onBind方法回调方法,这个方法会会回调一个跟服务端交互的Binder对象。
    这个绑定是异步的。要接受这个IBinder对象,客户端必须创建一个ServiceConnection的实例。并且把这个实例传给bindService方法。ServiceConnection对象包含了一个系统调用的传递IBinder对象的回调方法。
  3.实现service和activity之间的通信
  4.BIND_AUTO_CREATE表示在Activity和Service建立关联后会自动创建Service(即使之前没有创建Service也没有关系),这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
  5.绑定服务销毁:BIND_AUTO_CREATE绑定服务的时候,服务会被创建, 点击unbindService(connection);会销毁服务。如果即开启服务,又绑定服务,需要同时停止和解绑服务才能销毁服务。
    在解绑服务后,再解绑服务,程序就会异常退出。

八、started服务和bind服务的区别

  1.生命周期:通过started方式的服务会一直运行在后台,需要由组件本身或内部停止服务。
        bind方式服务依赖于绑定的组件

  2.参数传递:started方式可以给启动的服务对象传递参数,但无法获取服务中方法的返回值
        bind可以给启动的服务传递参数,也可以通过绑定的业务对象获取返回值

  3.生命周期:startService():onCreate-onStartCommend-onDestroy
        bindService():onCreate-onBind-onUnbind-onDestroy

九、IPC跨进程通信机制

  1.AIDL:(android interface Definition language)android 接口定义语言
      AIDL可以让Service与多个应用程序之间进行跨进程通信,从而实现多个应用程序共享同一个Service的功能。
  2.AIDL支持的类型:八大基本数据类型、String、CharSequence、List、map、自定义

十、IPC进程间通信步骤

  1.使用IDEA定义业务接口,通过ADT工具生成Java类,此类实现了进程间远程通信的代理
  2.编写自己的业务类(继承生成类中的Stub),实现业务类接口功能
  3.通过绑定服务的方式来暴露此业务,给其他组件提供功能
  4.调用者通过BindService的方式绑定服务从而获取绑定成功后的远程业务对象或本地业务对象。调用相关功能。

 

Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.ipcdemo", "com.example.ipcdemo.MyService"));
bindService(intent, serviceConnection, BIND_AUTO_CREATE);

 

 

 

  

 

 unbindService(connection);
posted on 2019-07-26 10:34  leill  阅读(164)  评论(0编辑  收藏  举报