关闭

Android AIDl来实现进程间通讯

标签: Android Aidl
3970人阅读 评论(0) 收藏 举报
分类:

Service组件

服务没有可视化接口,可以在后台运行。
生命周期:onCreate() ------->onStart(Intent intent , int startId)----------->onDestroy()
服务必须显示调用才可启动。
开机启动一个服务:
需要借助BroadCast监听开机事件,然后在onReceive()中启动服务。


启动服务的2中方法:context.startService()  和context.bindService()

1、context.startService()

此种方式启动service时会一次调用

context.startService() --------> onCreate()----->onStart()(service可被启动多次,如果service正在运行,则直接调用此方法)------>service running

context.stopService() --------> onDestroy() 

2、context.bindService()

此种方式启动service时会一次调用

context.startService() --------> onCreate()----->onBind()(只可绑定一次)------>service running

context.stopService() --------> onUnbind()----->onDestroy() 

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的运行状态等。

此时调用者和Service绑定在一起,Context退出了,service就会调用相应的onUnbind()方法。


AIDL(Android Interface  Definition Language)实现跨进程访问

AIDL(android接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务类。Service的实现类需要去继承这个stub服务类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:

service端进程:

首先建立一个android项目,并建立一个简单的AIDL服务(可看做一个接口),如下:

在包下建立一个aidl文件IService.aidl:

package com.service;

interface IService{
String getValue();
}

写一个Service类,在类中定义一个内部类MyServiceImpl ,该类实现aidl文件对应的stub服务类,如下:

  1. public class MyService extends Service{  
  2.       
  3.     private String text="";  
  4.     @Override  
  5.     public IBinder onBind(Intent intent) {  
  6.         return new MyServiceImpl();//此处必须返回一个 IService的实现类  
  7.     }  
  8.       
  9.     public class MyServiceImpl extends IService.Stub{  
  10.   
  11.   
  12.         @Override  
  13.         public String getValue() throws RemoteException {  
  14.             text = text +"io";  
  15.             return text;  
  16.         }  
  17.     }  
  18.       
  19. }  


在manifest文件中配置此service,如下:

<service android:name=".MyService">
<intent-filter >
<action android:name="com.service.serviceio"/>//此处是客户端用来访问AIDL服务的ID
</intent-filter>
</service>

调用服务的进程:

建立一个android项目作为客户端。

第一步:将service端项目生成的gen文件夹下的类(包括包)复制到调用服务的进程的src目录下。

第二步:写一个activity调用此服务:

  1. package com.client;  
  2.   
  3. import com.service.IService;  
  4. import android.app.Activity;  
  5. import android.content.ComponentName;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.ServiceConnection;  
  9. import android.os.Bundle;  
  10. import android.os.IBinder;  
  11. import android.os.RemoteException;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.widget.Button;  
  15. import android.widget.TextView;  
  16.   
  17.   
  18. public class IClient extends Activity implements OnClickListener{  
  19.       
  20.     private IService iService =null;  
  21.     private Button bind,invoke;  
  22.     private TextView text;  
  23.     private ServiceConnection serviceConnection = new ServiceConnection() {  
  24.           
  25.         @Override  
  26.         public void onServiceDisconnected(ComponentName name) {  
  27.             // TODO Auto-generated method stub  
  28.               
  29.         }  
  30.           
  31.         @Override  
  32.         public void onServiceConnected(ComponentName name, IBinder service) {  
  33.             // TODO Auto-generated method stub  
  34.             iService = IService.Stub.asInterface(service);  
  35.             invoke.setEnabled(true);  
  36.         }  
  37.     };  
  38.     @Override  
  39.     public void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.main);  
  42.         bind = (Button)findViewById(R.id.bind);  
  43.         invoke = (Button)findViewById(R.id.invoke);  
  44.         invoke.setEnabled(false);  
  45.         bind.setOnClickListener(this);  
  46.         invoke.setOnClickListener(this);  
  47.         text = (TextView)findViewById(R.id.text);  
  48.     }  
  49.     @Override  
  50.     public void onClick(View v) {  
  51.         // TODO Auto-generated method stub  
  52.         switch(v.getId()){  
  53.         case R.id.bind:  
  54.             bindService(new Intent("com.service.serviceio"), serviceConnection, Context.BIND_AUTO_CREATE);  
  55.             break;  
  56.         case R.id.invoke:  
  57.             try {  
  58.                 text.setText(iService.getValue());  
  59.             } catch (RemoteException e) {  
  60.                 // TODO Auto-generated catch block  
  61.                 e.printStackTrace();  
  62.             }  
  63.             break;  
  64.         }  
  65.     }  
  66. }  


此时就可实现访问service端的数据。

注意:AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据就需要进一步的处理。

AIDL服务支持的数据类型有:

java的简单类型:int char boolean 等

String 和CharSequence

List和Map;对象元素的类型也必须是AIDL服务支持的类型

AIDL自动生成的接口(需要import)

实现android.os.Parcelable接口的类(需要import)


来自于:http://blog.csdn.net/kay_wyong/article/details/6707645

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2688434次
    • 积分:20546
    • 等级:
    • 排名:第413名
    • 原创:379篇
    • 转载:79篇
    • 译文:0篇
    • 评论:329条
    博客专栏
    最新评论