ps:Service是运行在主线程中的!所以耗时操作会阻塞主线程!
一、本地service的应用以及生命周期
(1)通过startService来启动的Service
使用context.startService() 启动Service是会会经历:
context.startService() ->onCreate()- >onStart()->Service running
context.stopService() | ->onDestroy() ->Service stop
所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy
(2)通过bindService来启动的Service(知识应用有详细例子)
注:只有activities,services,和contentproviders可以绑定到一个service—你不能从一个broadcastreceiver绑定到service.
bindService启动的Service可以由unbindService来结束,也可以在Activity结束之后(onDestroy)自动结束。
使用使用context.bindService()启动Service会经历:
context.bindService()->onCreate()->onBind()->Service running
onUnbind() -> onDestroy() ->Service stop
从你的客户端绑定到一个service,你必须:
1实现ServiceConnection.
你的实现必须重写两个回调方法:
onServiceConnected()
系统调用这个来传送在service的onBind()中返回的IBinder.
OnServiceDisconnected()
Android系统在同service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用.
2调用bindService(),传给它ServiceConnection的实现.
3当系统调用你的onServiceConnected()方法时,你就可以使用接口定义的方法们开始调用service了.
4要与service断开连接,调用unbindService().
当你的客户端被销毁,它将从service解除绑定,但是你必须总是在你完成与service的交互时或当你的activity暂停于是service在不被使用时可以关闭此两种情况下解
除绑定.(下面会讨论更多在适当的时候绑定和解除绑定的问题.
使用这个ServiceConnection,客户端可以绑定到一个service,通过把它传给bindService().例如:
Intentintent = new Intent(this, LocalService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
第一个bindService()的参数是一个明确指定了要绑定的service的Intent.
第二个参数是ServiceConnection对象.
第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.。
PS:1、onStart可以多次调用,onBind只调用一次。
2、service混合调用时要stop和unbind两者都执行后之后才会销毁。
关于onRebind:http://www.zuiniuwang.com/?p=795
二、远程服务
可以参考:http://archive.cnblogs.com/a/2195980/和http://www.cnblogs.com/hibraincol/archive/2011/09/06/2169325.html
AIDL(Android Interface Definition Language) IPC机制是面向对象的,轻量级的。通过AIDL定义的接口可以实现服务器端与客户端的IPC通信。在Android上,一个进程不能简单的像访问本进程内存一样访问其他进程的内存。所以,进程间想要对话,需要将对象拆解为操作系统可以理解的基本数据单元,并且有序的通过进程边界。通过代码来实现这个数据传输过程是冗长乏味的,所幸的是android提供了AIDL工具来帮我们完成了此项工作。
注意:仅仅在你需要A应用程序的客户端访问B应用程序的服务器端来实现IPC通信,并且在服务器端需要处理多线程(客户端)访问的情况下使用AIDL。如果不需要使用到进程间的IPC通信,那么通过Binder接口实现将更为合适,如果需要实现进程间的IPC通信,但不需要处理多线程(多客户端),通过Messager接口来实现将更为合适。不管怎样,在使用AIDL之前,应先确保已理解了Bound Service。
AIDL接口的调用采用的是直接的函数调用方式,但你无法预知哪个进程(或线程)将调用该接口。同进程的线程调用和其他进程调用该接口之间是有所区别的:
定义AIDL接口
AIDL接口使用后缀名位.aidl的文件来定义,.aidl文件使用java语法编写,并且将该.aidl文件保存在 src/目录下(无论是服务端还是客户端都得保存同样的一份拷贝,也就是说只要是需要使用到该AIDL接口的应用程序都得在其src目录下拥有一份.aidl文件的拷贝)。
编译时,Android sdk 工具将会为 src/目录下的.aidl文件在 gen/ 目录下产生一个IBinder接口。服务端必须相应的实现该IBinder接口。客户端可以绑定该服务、调用其中的方法实现IPC通信。
创建一个用AIDL实现的服务端,需要以下几个步骤:
1. 创建.aidl文件:
该文件(YourInterface.aidl)定义了客户端可用的方法和数据的接口
2. 实现这个接口:
Android SDK将会根据你的.aidl文件产生AIDL接口。生成的接口包含一个名为Stub的抽象内部类,该类声明了所有.aidl中描述的方法,你必须在代码里继承该Stub类并且实现.aidl中定义的方法。
3.向客户端公开服务端的接口:
实现一个Service,并且在onBinder方法中返回第2步中实现的那个Stub类的子类(实现类)。
注意:
服务端AIDL的任何修改都必须的同步到所有的客户端,否则客户端调用服务端得接口可能会导致程序异常(因为此时客户端此时可能会调用到服务端已不再支持的接口
1. 创建.aidl文件
AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。重要的是必须导入所有非内置类型,哪怕是这些类型是在与接口相同的包中。
默认的AIDL支持一下的数据类型(这些类型不需要通过import导入):
对于其他的类型,在aidl中必须使用import导入,即使该类型和aidl处于同一包内。
定义一个服务端接口时,注意一下几点:
我们通过一个例子来说明:
将该.aidl文件保存在工程目录中的 src/目录下,当编译生成apk时,sdk 工具将会在 gen/ 目录下生成一个对应的IBiner接口的.java文件。
如果使用eclipse编写app,那么这个IBinder接口文件将会瞬间生成。
生成的接口包含一个名为Stub的抽象的内部类,该类声明了所有.aidl中描述的方法,
注意:
Stub还定义了少量的辅助方法,尤其是asInterface(),通过它或以获得IBinder(当applicationContext.bindService()成功调用时传递到客户端的onServiceConnected())并且返回用于调用IPC方法的接口实例
实现ADIL接口时需要注意一下几点:
客户端同样得访问该接口类(这里指YAIDLService),所以,如果服务端和客户端不在同一进程(应用程序)中,那么客户端也必须在 src/ 目录下拥有和服务端同样的一份.aidl文件的拷贝(同样是指,包名、类名、内容完全一模一样),客户端将会通过这个.aidl文件生成android.os.Binder接口——以此来实现客户端访问AIDL中的方法。
当客户端在onServiceConnected()回调方法中获得IBinder对象后,必须通过调用YourServiceInterface.Stub.asInterface(service)将其转化成为YourServiceInterface类型如上程序。
总结:这里给出调用远端AIDL接口的步骤:
1. 在 src/ 目录下包含.adil文件。
2. 声明一个IBinder
接口(通过.aidl文件生成的)的实例。
3. 实现ServiceConnection
.
4. 调用Context.bindService()绑定你的ServiceConnection实现类的对象(也就是远程服务端)。
5. 在onServiceConnected()
方法中会接收到IBinder对象(也就是服务端),调用YourInterfaceName.Stub.asInterface((IBinder)service)
将返回值转换为YourInterface类型。
6. 进行跨进程交互。
三、更新界面、多线程与传值
Service通过广播Broadcast更新Activity UI
http://www.eoeandroid.com/thread-68005-1-1.html
Android中Activity、Service和线程之间的通信(包含Handler)
Android线程交互(Handler+Thread 和 AsyncTask)博客园包含AsyncTask例子、知识汇总包含Handler例子
http://blog.csdn.net/super005/article/details/5827298