Service

1.Service生命周期

 Service完整生命周期从onCreate()开始到onDestroy结束,在onCreate( )中完成Service的初始化工作,在onDestroy( )中释放所有占用的资源。活动生命周期从onStart()开始,但没有与之对应的“停止”函数,因此可以粗略的认为活动生命周期是以onDestroy( )标志结束。

2.Service的使用方式有两种

启动方式绑定方式**启动方式**    通过调用Context.startService()启动Service,通过调用Context.stopService()或者Service.stopSelf()停止Service.因此Service一定是由其他的组件启动的,但停止过程可以通过其他组件或自身完成    在启动方式中,启动Service的组件不能够获取到Service的对象实例,因此无法调用Service中的任何函数,也不能够获得Service中的任何状态和数据信息。    能够以启动方式使用的Service,需要具备自管理的能力,而且不需要通过函数调用来获取Service的功能和数据。**绑定方式**    Service的使用时通过服务链接(connetction)实现的,服务链接能够获取Service的对象实例,因此绑定Service的组件可以调用Service中实现的函数,或之间获取Service中的状态和数据信息。    使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接    如果在绑定过程中Service没有启动。Context.bindService()会自动启动Service,而且同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务。**启动方式和绑定方式的结合**    这两种使用方法并不是完全独立的,在某些情况下可以混合使用。    以MP3为例,在后台工作的Service通过Context.startService()启动某个音乐播放,但在播放过程中如果用户需要暂停音乐,则需要通过Context.bindService()获取服务链接和Service对象实例,进而通过调用Service对象实例中的函数,暂停音乐播放过程,并保存相关信息。    在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务连接关闭后,Service才能够真正的停止。

3.本地服务

本地服务的调用者和服务都在同一个程序中,是不需要跨进程就可以实现服务的调用。本地服务涉及服务的建立、启动和停止,服务的绑定和取消绑定,以及如何在线程中实现服务。**服务管理**    服务管理主要指服务的启动和停止    首先说明如何在代码中实现Service。Service是一段在后台运行、没有用户界面的代码。    在完成Service代码和在AndroidManifest.xml文件中注册后,下面来说明如何启动和停止Service。有两种方式,分别是 显式启动和隐式启动。    显式启动需要在Intent中指明Service所在的类,并调用startService(Intent)启动Service,实例代码如下:
final Intent serviceIntent=new Intent(this,RandomService.class);startService(serviceIntent);
    上面代码中,Intent指明了启动的Service所在类为RandomService    隐式启动则需要在注册Service时,声明Intent-filter的action属性    在隐式启动Service时,需要设置Intent的action属性,这样则可以在不声明Service所在类的情况下启动服务。实例代码如下:
final Intent serviceIntent=new Intent();serviceIntent.setAction("com.RandomService");
        如果Service和调用服务的组件在同一个应用程序中,可以使用显式启动和隐式启动,显式启动更加易于使用,且代码简洁。如果服务和调用服务的组件在不同的应用程序中,则只能使用隐式启动。        无论是显式启动还是隐式启动,停止Service的方法都是相同的,将启动Service的Intent传递给stopService(Intent)即可。实例代码如下:
stopService(serviceIntent)
        在首次调用startService(Intent)启动Service后,系统会先后调用onCreate()和onStart()        如果是第二次调用startService(Intent),系统则仅调用onStart(),而不再调用onCreate()        在调用stopService(Intent)停止Service时,系统会调用onDestroy()        无论调用过多少次startService(Intent),在调用stopService(Intent)时,系统仅调用一次onDestroy()**使用线程**    在Android系统中,Activity、Service和BroadcastRecever都是工作在主线程上的,因此任何耗时的处理过程都会降低用户界面的响应速度,甚至导致用户界面失去响应。    当用户界面失去响应超过5秒,Android系统会允许用户强行关闭应用程序。    因此,较好的解决方式是将耗时的处理过程转移到子线程上,这样可以缩短主线程的事件处理时间,从而避免用户界面长时间失去响应。    “耗时的处理过程”一般指复杂运算过程,大量的文件操作,存在演示的网络通讯和数据库操作等等。    线程是独立的程序单元,多个线程可以并行工作。在多处理器系统中,每个CPU单独运行一个线程,因此线程是并行工作的。    但在单处理器系统中,处理器会给每个线程一小段时间,在这个时间内线程是被执行的,然后处理器执行下一个线程,这样就产生了线程并行运行的假象。    无论线程是否真的并行工作,在宏观上可以认为子线程是独立于主线程,且能与主线程并行工作的程序单元。    在Java语言中,建立和使用线程比较简单,首先需要实现java的Runnable接口,并重载run()函数,在run()中放置代码的主体部分。
private Runnable backgroudWork=new Runnable(){        @Override        public void run()        {            //过程代码        }    }
            然后创建Thread对象,并将Runnable对象作为参数传递给Thread对象            在Thread的构造函数中,第1个参数用来表示线程组,第2个参数是需要执行的Runnable对象,第3个参数是线程的名称
private Thread workThread;workThread=new Thread(null,backgroudWork,"workThread");
        最后调用

workThread.start();

        当线程在run()方法返回后,线程就自动终止了        当然也可以调用stop()在外部终止线程,但是这种方法并不推荐使用,因为这个方法并不安全,有一定可能性会产生异常。        最好的方法是通知线程自行终止,一般调用interrupt()方法通告线程准备终止,线程会释放它正在使用的资源,在完成所有的清理工作后自行关闭。
workThread.interrupt()
    其实interrupt()方法并不能直接终止线程,只是改变了线程内部的一个布尔值,run()方法能够检测到这个布尔值的改变,从而在适当的时候释放资源和终止线程。    在run()中的代码一般通过Thread.interrupted()方法查询线程是否被中断    一般情况下,子线程需要无限运行,除非外部调用interrupt()方法中断线程,所以通常会将程序主体放置在while()函数中,并调用Thread.interrupted()方法判断线程是否应被中断    下面的代码中,以1秒为间隔循环检测线程是否被中断
public void run(){    while(!Thread.interrupted())    {        //过程代码        Thread.sleep(1000);    }}
        当线程在休眠过程中线程被中断,则会产生InterruptedException异常        因此代码中需要捕获InterruptedException异常,保证安全终止线程
public void run(){    try{    while(!Thread.interrupted())    {        //过程代码        Thread.sleep(1000);    }    }catch(InterruptedException e)    {        e.printStackTrace();    }}
使用Handler更新用户界面    Handler允许将Runnable对象发送到线程的消息队列中,每个Handler实例绑定到一个单独的线程和消息队列上

4.远程服务

    **进程间通信**    在Android系统中,每个应用程序在各自的进程中运行,而且处于安全原因的考虑,这些进程之间彼此是隔离的,进程之间传递数据和对象,需要使用Andorid支持的进程间通信(IPC)机制    在Unix/Linux系统中,传统的IPC机制包括共享内存、管道、消息队列和socket等等,这些ipc机制虽然被广泛使用,但仍然存在着固有的缺陷,如容易产生错误、难于维护等等。    在Android系统中,没有使用传统的ipc机制,而是采用Intent和远程服务的方式实现IPC,使应用程序具有更好的独立性和鲁棒性。    Android系统允许应用程序使用Intent启动Activity和Service,同时Intent可以传递数据,是一种简单、高效、易于使用的IPC机制。    Android系统的另一种IPC机制就是远程服务,服务和调用者在不同的两个进程中,调用过程需要跨越进程才能实现    **服务的创建和调用**    Android系统中使用远程服务,一般按照以下3个步骤实现    1.使用AIDL语言定义远程服务的接口    2.根据AIDL语言定义的接口。在具体的Service类中实现接口中定义的方法和属性。    3.在需要调用远程服务的组件中,通过相同的AIDL接口文件,调用远程服务    在Android系统中,进程之间不能直接访问相互的内存控件,因此为了使数据能够在不同进程中传递,数据必须转换成能够穿越进程边界的系统级原语,同时,在数据完成进程边界穿越后,还需要转换回原有的格式    AIDL是Android系统自定义的接口描述语言,可以简化进程间数据格式转化和数据交换的代码,通过定义Service内部的公共方法,允许在不同进程间的调用者和Service之间相互传递数据。    AIDL的IPC机制、COM和Corba都是基于接口的轻量级进程通信机制    AIDL语言的语法和java的接口定义非常相似,唯一不同之处是AIDL允许定义函数参数的传递方向    AIDL支持3种方向:in、out和inout        标识为in的参数将从调用者传递到远程服务中        标识为out的参数将从远程服务传递到调用者中        标识为inout的参数将先从调用者传递到远程服务中,再从远程服务返回给调用者    如果不标识参数的传递方向,默认所有函数的传递方向为in    处于性能方向的考虑,不要在参数中标识不需要的传递方向    远程服务的创建和调用需要使用AIDL语言,一般分为一下几个过程        1.使用AIDL语言定义远程服务的接口        2.通过继承Service类实现远程服务        3.绑定和使用远程服务

更多相关文章

  1. 加速Android(安卓)Studio/Gradle构建
  2. android layout Java代码生成器
  3. Android高手进阶教程(五)之----Android(安卓)中LayoutInflater的
  4. Android夜间模式实现,通过在window上加一层半透明的View
  5. launcher修改--获取屏幕缩略(预览)图
  6. 关于Android中传递数据的一些讨论
  7. Intent 详解
  8. Android(安卓)自定义View - 启航 一般View定义
  9. Android异步加载图像(含线程池,缓存方法)

随机推荐

  1. Android(安卓)ActionBar完全解析上
  2. Android:解决Camera.open()运行时异常Run
  3. android XML积累
  4. Android自定义RadioGroup
  5. xe5 android tts(Text To Speech)
  6. Android(安卓)新兴的UI模式——侧边导航
  7. 关于Android文件Apk下载的那点事
  8. Android的SD卡文件读写
  9. Android之使用微信开放api (一)
  10. Android(安卓)混淆 (不定期完善第三方混