Android 进程间通信
一、 本地服务与远程服务(AIDL服务)区别
本地服务:无法供在设备上运行的其他应用程序访问。一般而言, 这些服务类型仅支持承载该服务的应用程序。onBind方法为在同一设备上运行的外部应用程序提供一个接口来与服务通信。
启动服务:由Context.startService()启动。
停止服务:客户端调用服务的Context.stopService()或者服务自己调用stopSelf().
Import android.app.Service;
Public class TestService extends Service
{
@Override
Public void onCreate(){
{
Super.onCreate();
}
@Override
Public IBinder onBind(Intent intent){
{
Return null;
}
}
Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。
启动服务:bindService
停止服务:unbindService
11: public class LocalServiceDemoActivity extends Activity {
12:
13: private ServiceConnection serviceConnection = new ServiceConnection() {
14:
15: @Override
16: public void onServiceConnected(ComponentName name, IBinder service) {
17: countService = (ICountService) service;
20: }
21:
22: @Override
23: public void onServiceDisconnected(ComponentName name) {
24: countService = null;
25: }
26:
27: };
28:
29: private ICountService countService;
30:
31: /** Called when the activity is first created. */
32: @Override
33: public void onCreate(Bundle savedInstanceState) {
34: super.onCreate(savedInstanceState);
35: setContentView(R.layout.main);
36: this.bindService(new Intent("com.easymorse.CountService"),
37: this.serviceConnection, BIND_AUTO_CREATE);
38: }
39:
40: @Override
41: protected void onDestroy() {
42: super.onDestroy();
43: this.unbindService(serviceConnection);
44: }
45: }
远程服务: 使用AIDL(Android Interface Definition Language---Android接口定义语言)向客户端定义自身。onBind方法返回非空。可通过进程间通信(Context.bindService())进行调用。
二、 AIDL服务
要构建远程服务,执行以下步骤:
(1) 编写一个AIDL文件来向客户端定义接口。包名与Android项目同。
(2) 将AIDL文件添加到Eclipse项目的src目录下。编译器将在gen下自动生成java接口。
(3) 实现一个服务并从onBind()方法返回所生成的接口。
(4) 将服务配置添加到AndroidManifest.xml文件中。
例:股票报价服务的AIDL定义
Package com.androidbook.stockquoteservice;
Interface IstockQuoteService
{
Double getQuote(String ticker);
}
随后,编译器将在gen目录下生成IstockQuoteService.java文件。
名为Stub的static final抽象类扩展了android.os.Binder并实现了IstockQuoteService.
名为Proxy的内部类实现了IstockQuoteService,后者是Stub类的代理。
在服务类中实现AIDL接口:
Public class StockQuoteService extends Service
{
Public class StockQuoteServiceImpl extends IstockQuoteService.Stub
{ //与本地需要与activity交互的service区别主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
@Override
Public double getQuote(String ticker) throw RemoteException
{
Return 200.0;
}
}
@Override
Public void onCreate(){ super.onCreate();}
@Override
Public void onDestroy(){ super.onDestroy();}
@Override
Public void onStart(Intent intent,int startId){ super.onStart(intent,startId);}
@Override
Public Ibinder onBind(Intent intent){ return new StockQuoteServiceImpl();}
将服务向客户端公开:
<service android:name="StockQuoteService">
<intent-filter>
<action android:name="com.androidbook.stockquoteservice.IStockQuoteService" />
</service>
三、 从客户端应用程序调用服务
当客户端与服务通信时,它们必须有一个协议或契约。在Android中,这个契约就是AIDL。所以,使用服务的第一步是,获取服务的AIDL文件并将其复制到客户端项目中。
提供ServiceConnection接口的实现:
private ServiceConnection mServiceConn = new ServiceConnection()
{
public void onServiceConnected(ComponentName name, IBinder service) {
stockService=IStockQuoteService.Stub.asInterface(service) ;
}
public void onServiceDisconnected(ComponentName name) {
stockService = null ;
}
} ;
四、 向服务传递复杂的类型
实现Parcelable接口
延伸阅读:
1.http://www.eoeandroid.com/thread-36249-1-1.html
2.http://yangguangfu.iteye.com/blog/779410
http://www.cnblogs.com/GnagWang/archive/2010/11/29/1891617.html